Browse Source

Minor naming cleanups

pull/16/head
Ian Chamberlain 2 years ago
parent
commit
ceacc3387d
No known key found for this signature in database
GPG Key ID: AE5484D09405AA60
  1. 15
      citro3d/examples/triangle.rs
  2. 32
      citro3d/src/attrib.rs
  3. 18
      citro3d/src/buffer.rs
  4. 6
      citro3d/src/shader.rs

15
citro3d/examples/triangle.rs

@ -1,7 +1,10 @@
//! This example demonstrates the most basic usage of `citro3d`: rendering a simple
//! RGB triangle (sometimes called a "Hello triangle") to the 3DS screen.
#![feature(allocator_api)] #![feature(allocator_api)]
use citro3d::attrib::{self, AttrInfo}; use citro3d::attrib::{self};
use citro3d::buffers::{self, BufInfo}; use citro3d::buffer::{self};
use citro3d::render::{ClearFlags, Target}; use citro3d::render::{ClearFlags, Target};
use citro3d::{include_aligned_bytes, shader}; use citro3d::{include_aligned_bytes, shader};
use citro3d_sys::C3D_Mtx; use citro3d_sys::C3D_Mtx;
@ -110,7 +113,7 @@ fn main() {
); );
} }
instance.draw_arrays(buffers::Primitive::Triangles, vbo_idx); instance.draw_arrays(buffer::Primitive::Triangles, vbo_idx);
}); });
}; };
@ -119,9 +122,9 @@ fn main() {
} }
} }
fn prepare_vbos(vbo_data: &[Vertex]) -> buffers::Index { fn prepare_vbos(vbo_data: &[Vertex]) -> buffer::Index {
// Configure attributes for use with the vertex shader // Configure attributes for use with the vertex shader
let mut attr_info = AttrInfo::get_mut().expect("failed to get global attr info"); let mut attr_info = attrib::Info::get_mut().expect("failed to get global attr info");
let reg0 = attrib::Register::new(0).unwrap(); let reg0 = attrib::Register::new(0).unwrap();
let reg1 = attrib::Register::new(1).unwrap(); let reg1 = attrib::Register::new(1).unwrap();
@ -143,7 +146,7 @@ fn prepare_vbos(vbo_data: &[Vertex]) -> buffers::Index {
.unwrap(); .unwrap();
// Configure buffers // Configure buffers
let mut buf_info = BufInfo::get_mut().unwrap(); let mut buf_info = buffer::Info::get_mut().unwrap();
let buf_idx = buf_info.add(vbo_data, &attr_info).unwrap(); let buf_idx = buf_info.add(vbo_data, &attr_info).unwrap();
buf_idx buf_idx

32
citro3d/src/attrib.rs

@ -1,7 +1,7 @@
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::sync::{LazyLock, RwLock}; use std::sync::{LazyLock, RwLock};
static ATTR_INFO: LazyLock<RwLock<AttrInfo>> = LazyLock::new(|| { static INFO: LazyLock<RwLock<Info>> = LazyLock::new(|| {
let raw = unsafe { let raw = unsafe {
// TODO: should we check is_null() here? // TODO: should we check is_null() here?
let info = citro3d_sys::C3D_GetAttrInfo(); let info = citro3d_sys::C3D_GetAttrInfo();
@ -9,13 +9,14 @@ static ATTR_INFO: LazyLock<RwLock<AttrInfo>> = LazyLock::new(|| {
info info
}; };
RwLock::new(AttrInfo { raw }) RwLock::new(Info { raw })
}); });
pub struct AttrInfo { pub struct Info {
raw: *mut citro3d_sys::C3D_AttrInfo, raw: *mut citro3d_sys::C3D_AttrInfo,
} }
#[derive(Debug, Clone, Copy)]
pub struct Register(libc::c_int); pub struct Register(libc::c_int);
impl Register { impl Register {
@ -24,12 +25,12 @@ impl Register {
// that gets atomically increasing indices or something? Or look at // that gets atomically increasing indices or something? Or look at
// <https://3dbrew.org/wiki/GPU/Internal_Registers> and define some consts // <https://3dbrew.org/wiki/GPU/Internal_Registers> and define some consts
// or lookup functions // or lookup functions
Ok(Self(n as _)) Ok(Self(n.into()))
} }
} }
#[must_use] #[must_use]
pub struct Index(libc::c_int); pub struct Index(u8);
#[repr(u32)] #[repr(u32)]
pub enum Format { pub enum Format {
@ -41,18 +42,18 @@ pub enum Format {
// SAFETY: the RWLock ensures unique access when mutating the global struct, and // SAFETY: the RWLock ensures unique access when mutating the global struct, and
// we trust citro3d to Do The Right Thing™ and not mutate it otherwise. // we trust citro3d to Do The Right Thing™ and not mutate it otherwise.
unsafe impl Sync for AttrInfo {} unsafe impl Sync for Info {}
unsafe impl Send for AttrInfo {} unsafe impl Send for Info {}
impl AttrInfo { impl Info {
/// Get a reference to the global attribute info. /// Get a reference to the global attribute info.
pub fn get() -> crate::Result<impl Deref<Target = Self>> { pub fn get() -> crate::Result<impl Deref<Target = Self>> {
Ok(ATTR_INFO.try_read()?) Ok(INFO.try_read()?)
} }
/// Get a mutable reference to the global attribute info. /// Get a mutable reference to the global attribute info.
pub fn get_mut() -> crate::Result<impl DerefMut<Target = Self>> { pub fn get_mut() -> crate::Result<impl DerefMut<Target = Self>> {
Ok(ATTR_INFO.try_write()?) Ok(INFO.try_write()?)
} }
/// Add an attribute loader to the attribute info. By default, the resulting /// Add an attribute loader to the attribute info. By default, the resulting
@ -65,9 +66,13 @@ impl AttrInfo {
) -> crate::Result<Index> { ) -> crate::Result<Index> {
let count = count.try_into()?; let count = count.try_into()?;
let idx = let ret =
unsafe { citro3d_sys::AttrInfo_AddLoader(self.raw, register.0, format as u32, count) }; unsafe { citro3d_sys::AttrInfo_AddLoader(self.raw, register.0, format as u32, count) };
let Ok(idx) = ret.try_into() else {
return Err(crate::Error::FailedToInitialize)
};
Ok(Index(idx)) Ok(Index(idx))
} }
@ -75,6 +80,7 @@ impl AttrInfo {
if indices.len() > 16 { if indices.len() > 16 {
return Err(crate::Error::TooManyAttributes); return Err(crate::Error::TooManyAttributes);
} }
let attr_count: libc::c_int = indices.len().try_into().unwrap();
let mut bytes: Vec<u8> = indices let mut bytes: Vec<u8> = indices
.windows(2) .windows(2)
@ -85,7 +91,7 @@ impl AttrInfo {
_ => unreachable!(), // window size of 2 == always 1 or 2 elements _ => unreachable!(), // window size of 2 == always 1 or 2 elements
}; };
// each value is a nibble, combine them into a byte // each value is a nibble, combine them into a byte
lo as u8 | (hi as u8) << 4 lo | (hi << 4)
}) })
.collect(); .collect();
@ -96,7 +102,7 @@ impl AttrInfo {
unsafe { unsafe {
(*self.raw).permutation = permutation; (*self.raw).permutation = permutation;
(*self.raw).attrCount = indices.len() as _; (*self.raw).attrCount = attr_count;
} }
Ok(()) Ok(())
} }

18
citro3d/src/buffers.rs → citro3d/src/buffer.rs

@ -1,27 +1,29 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem::MaybeUninit;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::sync::{LazyLock, RwLock}; use std::sync::{LazyLock, RwLock};
use crate::attrib; use crate::attrib;
static BUF_INFO: LazyLock<RwLock<BufInfo>> = LazyLock::new(|| { static BUF_INFO: LazyLock<RwLock<Info>> = LazyLock::new(|| {
let raw = unsafe { let raw = unsafe {
let info = citro3d_sys::C3D_GetBufInfo(); let info = citro3d_sys::C3D_GetBufInfo();
citro3d_sys::BufInfo_Init(info); citro3d_sys::BufInfo_Init(info);
info info
}; };
RwLock::new(BufInfo { raw }) RwLock::new(Info { raw })
}); });
pub struct BufInfo { /// Vertex attribute info. This struct can be used to
pub struct Info {
raw: *mut citro3d_sys::C3D_BufInfo, raw: *mut citro3d_sys::C3D_BufInfo,
} }
// SAFETY: the RWLock ensures unique access when mutating the global struct, and // SAFETY: the RWLock ensures unique access when mutating the global struct, and
// we trust citro3d to Do The Right Thing™ and not mutate it otherwise. // we trust citro3d to Do The Right Thing™ and not mutate it otherwise.
unsafe impl Sync for BufInfo {} unsafe impl Sync for Info {}
unsafe impl Send for BufInfo {} unsafe impl Send for Info {}
// TODO: is this a good name? It's more like a "handle" to the VBO data, or a slice. // TODO: is this a good name? It's more like a "handle" to the VBO data, or a slice.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -50,7 +52,7 @@ pub enum Primitive {
GeometryPrim = ctru_sys::GPU_GEOMETRY_PRIM, GeometryPrim = ctru_sys::GPU_GEOMETRY_PRIM,
} }
impl BufInfo { impl Info {
/// Get a reference to the global buffer info. /// Get a reference to the global buffer info.
pub fn get() -> crate::Result<impl Deref<Target = Self>> { pub fn get() -> crate::Result<impl Deref<Target = Self>> {
Ok(BUF_INFO.try_read()?) Ok(BUF_INFO.try_read()?)
@ -64,7 +66,7 @@ impl BufInfo {
pub fn add<'vbo, T>( pub fn add<'vbo, T>(
&mut self, &mut self,
vbo_data: &'vbo [T], vbo_data: &'vbo [T],
attrib_info: &attrib::AttrInfo, attrib_info: &attrib::Info,
) -> crate::Result<Index<'vbo>> { ) -> crate::Result<Index<'vbo>> {
let stride = std::mem::size_of::<T>().try_into()?; let stride = std::mem::size_of::<T>().try_into()?;
let attrib_count = attrib_info.count(); let attrib_count = attrib_info.count();
@ -73,8 +75,6 @@ impl BufInfo {
let res = unsafe { let res = unsafe {
citro3d_sys::BufInfo_Add( citro3d_sys::BufInfo_Add(
self.raw, self.raw,
// TODO: figure out how the hell to encode the lifetime of this
// data so that we don't try to use it after it's destroyed...
vbo_data.as_ptr().cast(), vbo_data.as_ptr().cast(),
stride, stride,
attrib_count, attrib_count,

6
citro3d/src/shader.rs

@ -11,8 +11,8 @@ pub mod macros;
/// A PICA200 shader program. It may have one or both of: /// A PICA200 shader program. It may have one or both of:
/// ///
/// * A vertex [shader instance](Instance) /// * A vertex shader [`Library`]
/// * A geometry [shader instance](Instance) /// * A geometry shader [`Library`]
/// ///
/// The PICA200 does not support user-programmable fragment shaders. /// The PICA200 does not support user-programmable fragment shaders.
pub struct Program { pub struct Program {
@ -86,7 +86,7 @@ impl Drop for Program {
/// one or more [`Entrypoint`]s, but most commonly has one vertex shader and an /// one or more [`Entrypoint`]s, but most commonly has one vertex shader and an
/// optional geometry shader. /// optional geometry shader.
/// ///
/// This is the result of parsing a shader binary (shbin), and the resulting /// This is the result of parsing a shader binary (`.shbin`), and the resulting
/// [`Entrypoint`]s can be used as part of a [`Program`]. /// [`Entrypoint`]s can be used as part of a [`Program`].
pub struct Library(*mut ctru_sys::DVLB_s); pub struct Library(*mut ctru_sys::DVLB_s);

Loading…
Cancel
Save