Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
# \___\/ ==\______\/\_____\__\/ ==\______/_____,´ /==\_____\___\/==\_______\/
# \_____\,´

# On nightly only
#cargo-features = ["panic-immediate-abort"]

[package]
name = "retrofire"
description = "90s style software 3D renderer and graphics tools."
Expand Down Expand Up @@ -67,12 +70,21 @@ debug = 1
[profile.bench]
opt-level = 3
codegen-units = 1
lto = "thin"
lto = "fat"

[profile.dev]
opt-level = 1
split-debuginfo = "unpacked"

[profile.min]
inherits = "release"
opt-level = 3
codegen-units = 1
lto = "fat"
debug = 0
strip = true
panic = "abort"
#panic = "immediate-abort" # On nightly only

[[bench]]
name = "fill"
Expand Down
21 changes: 12 additions & 9 deletions benches/clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ use retrofire_core::{
//#[global_allocator]
//static ALLOC: AllocProfiler = AllocProfiler::system();

#[divan::bench(args = [1, 10, 100, 1000, 10_000])]
#[divan::bench(args = [1, 10, 100, 1000, 10_000], min_time = 1)]
fn clip_mixed(b: Bencher, n: usize) {
let rng = &mut DefaultRng::default();
let pts = pt3(-10.0, -10.0, -10.0)..pt3(10.0, 10.0, 10.0);
let proj = orthographic(pt3(-1.0, -1.0, -1.0), pt3(1.0, 1.0, 1.0));

let mut out = Vec::with_capacity(n);
b.with_inputs(|| {
repeat_with(|| {
let vs = array::from_fn(|_| {
Expand All @@ -32,18 +33,19 @@ fn clip_mixed(b: Bencher, n: usize) {
})
.input_counter(|tris| ItemsCount::of_iter(tris))
.bench_local_values(|tris| {
let mut out = Vec::new();
out.clear();
view_frustum::clip(tris.as_slice(), &mut out);
out
out.len()
})
}

#[divan::bench(args = [1, 10, 100, 1000, 10_000])]
#[divan::bench(args = [1, 10, 100, 1000, 10_000], min_time = 1)]
fn clip_all_inside(b: Bencher, n: usize) {
let rng = &mut DefaultRng::default();
let pts = pt3(-1.0, -1.0, -1.0)..pt3(1.0, 1.0, 1.0);
let proj = orthographic(pt3(-1.0, -1.0, -1.0), pt3(1.0, 1.0, 1.0));

let mut out = Vec::with_capacity(n);
b.with_inputs(|| {
repeat_with(|| {
let vs = array::from_fn(|_| {
Expand All @@ -56,18 +58,19 @@ fn clip_all_inside(b: Bencher, n: usize) {
})
.input_counter(|tris| ItemsCount::of_iter(tris))
.bench_local_values(|tris| {
let mut out = Vec::new();
out.clear();
view_frustum::clip(tris.as_slice(), &mut out);
out
out.len()
})
}

#[divan::bench(args = [1, 10, 100, 1000, 10_000])]
#[divan::bench(args = [1, 10, 100, 1000, 10_000], min_time = 1)]
fn clip_all_outside(b: Bencher, n: usize) {
let mut rng = DEFAULT_RNG;
let pts = pt3(2.0, -10.0, -10.0)..pt3(10.0, 10.0, 10.0);
let proj = orthographic(pt3(-1.0, -1.0, -1.0), pt3(1.0, 1.0, 1.0));

let mut out = Vec::with_capacity(n);
b.with_inputs(|| {
repeat_with(|| {
let vs = ([pts.start; 3]..[pts.end; 3])
Expand All @@ -80,9 +83,9 @@ fn clip_all_outside(b: Bencher, n: usize) {
})
.input_counter(|tris| ItemsCount::of_iter(tris))
.bench_local_values(|tris| {
let mut out = Vec::with_capacity(tris.len());
out.clear();
view_frustum::clip(tris.as_slice(), &mut out);
out
out.len()
})
}

Expand Down
6 changes: 2 additions & 4 deletions benches/fill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,8 @@ fn gouraud(b: Bencher, sz: f32) {
});
});

let buf = Buf2::new_from(
(1024, 1024),
buf.data().into_iter().map(|c| c.to_color3()),
);
let buf =
Buf2::new_from((1024, 1024), buf.data().iter().map(|c| c.to_color3()));
save_ppm("benches_fill_color.ppm", buf).unwrap();
}

Expand Down
40 changes: 40 additions & 0 deletions clip_arrays.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

clip fastest │ slowest │ median │ mean │ samples │ iters
├─ clip_all_inside │ │ │ │ │
│ ├─ 1 121.6 ns │ 6.734 µs │ 124.6 ns │ 192.4 ns │ 100 │ 100
│ │ 8.217 Mitem/s │ 148.4 Kitem/s │ 8.019 Mitem/s │ 5.196 Mitem/s │ │
│ ├─ 10 481.9 ns │ 3.401 µs │ 489.4 ns │ 527.6 ns │ 100 │ 400
│ │ 20.74 Mitem/s │ 2.94 Mitem/s │ 20.43 Mitem/s │ 18.95 Mitem/s │ │
│ ├─ 100 1.299 µs │ 14.45 µs │ 1.402 µs │ 1.585 µs │ 100 │ 100
│ │ 76.94 Mitem/s │ 6.92 Mitem/s │ 71.29 Mitem/s │ 63.08 Mitem/s │ │
│ ├─ 1000 9.797 µs │ 55.06 µs │ 9.962 µs │ 12.42 µs │ 100 │ 100
│ │ 102 Mitem/s │ 18.16 Mitem/s │ 100.3 Mitem/s │ 80.51 Mitem/s │ │
│ ╰─ 10000 268.9 µs │ 444.8 µs │ 304.2 µs │ 317.1 µs │ 100 │ 100
│ 37.17 Mitem/s │ 22.48 Mitem/s │ 32.86 Mitem/s │ 31.53 Mitem/s │ │
├─ clip_all_outside │ │ │ │ │
│ ├─ 1 70.45 ns │ 71.41 ns │ 71.04 ns │ 70.97 ns │ 100 │ 6400
│ │ 14.19 Mitem/s │ 14 Mitem/s │ 14.07 Mitem/s │ 14.08 Mitem/s │ │
│ ├─ 10 140.4 ns │ 162.3 ns │ 142 ns │ 142.2 ns │ 100 │ 3200
│ │ 71.21 Mitem/s │ 61.6 Mitem/s │ 70.38 Mitem/s │ 70.27 Mitem/s │ │
│ ├─ 100 325 ns │ 337.3 ns │ 327.9 ns │ 328.1 ns │ 100 │ 1600
│ │ 307.6 Mitem/s │ 296.4 Mitem/s │ 304.9 Mitem/s │ 304.7 Mitem/s │ │
│ ├─ 1000 3.085 µs │ 11.86 µs │ 3.109 µs │ 3.203 µs │ 100 │ 100
│ │ 324 Mitem/s │ 84.29 Mitem/s │ 321.5 Mitem/s │ 312.1 Mitem/s │ │
│ ╰─ 10000 25.36 µs │ 38.05 µs │ 25.84 µs │ 26.03 µs │ 100 │ 100
│ 394.2 Mitem/s │ 262.8 Mitem/s │ 386.8 Mitem/s │ 384.1 Mitem/s │ │
╰─ clip_mixed │ │ │ │ │
├─ 1 124.7 ns │ 281 ns │ 205.6 ns │ 205.5 ns │ 100 │ 3200
│ 8.017 Mitem/s │ 3.557 Mitem/s │ 4.862 Mitem/s │ 4.865 Mitem/s │ │
├─ 10 1.137 µs │ 4.934 µs │ 1.81 µs │ 1.875 µs │ 100 │ 400
│ 8.787 Mitem/s │ 2.026 Mitem/s │ 5.523 Mitem/s │ 5.33 Mitem/s │ │
├─ 100 12.63 µs │ 20.31 µs │ 16.45 µs │ 16.47 µs │ 100 │ 100
│ 7.911 Mitem/s │ 4.922 Mitem/s │ 6.077 Mitem/s │ 6.068 Mitem/s │ │
├─ 1000 147.5 µs │ 313.6 µs │ 159 µs │ 162.7 µs │ 100 │ 100
│ 6.776 Mitem/s │ 3.188 Mitem/s │ 6.288 Mitem/s │ 6.145 Mitem/s │ │
╰─ 10000 1.544 ms │ 2.106 ms │ 1.598 ms │ 1.638 ms │ 100 │ 100
6.474 Mitem/s │ 4.746 Mitem/s │ 6.256 Mitem/s │ 6.104 Mitem/s │ │

40 changes: 40 additions & 0 deletions clip_no_changes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

clip fastest │ slowest │ median │ mean │ samples │ iters
├─ clip_all_inside │ │ │ │ │
│ ├─ 1 252.6 ns │ 6.016 µs │ 260.6 ns │ 319.9 ns │ 100 │ 100
│ │ 3.957 Mitem/s │ 166.2 Kitem/s │ 3.835 Mitem/s │ 3.125 Mitem/s │ │
│ ├─ 10 625.4 ns │ 1.26 µs │ 641.1 ns │ 647.9 ns │ 100 │ 400
│ │ 15.98 Mitem/s │ 7.93 Mitem/s │ 15.59 Mitem/s │ 15.43 Mitem/s │ │
│ ├─ 100 1.376 µs │ 13.15 µs │ 1.479 µs │ 1.664 µs │ 100 │ 100
│ │ 72.63 Mitem/s │ 7.602 Mitem/s │ 67.6 Mitem/s │ 60.06 Mitem/s │ │
│ ├─ 1000 9.529 µs │ 47.56 µs │ 9.637 µs │ 10.16 µs │ 100 │ 100
│ │ 104.9 Mitem/s │ 21.02 Mitem/s │ 103.7 Mitem/s │ 98.36 Mitem/s │ │
│ ╰─ 10000 125.3 µs │ 500.6 µs │ 131.7 µs │ 164.8 µs │ 100 │ 100
│ 79.79 Mitem/s │ 19.97 Mitem/s │ 75.91 Mitem/s │ 60.64 Mitem/s │ │
├─ clip_all_outside │ │ │ │ │
│ ├─ 1 204.1 ns │ 207 ns │ 205.4 ns │ 205.5 ns │ 100 │ 3200
│ │ 4.898 Mitem/s │ 4.83 Mitem/s │ 4.866 Mitem/s │ 4.865 Mitem/s │ │
│ ├─ 10 281.7 ns │ 309.1 ns │ 284.8 ns │ 285 ns │ 100 │ 1600
│ │ 35.49 Mitem/s │ 32.34 Mitem/s │ 35.1 Mitem/s │ 35.07 Mitem/s │ │
│ ├─ 100 397.7 ns │ 1.069 µs │ 424.5 ns │ 452.9 ns │ 100 │ 1600
│ │ 251.4 Mitem/s │ 93.46 Mitem/s │ 235.5 Mitem/s │ 220.7 Mitem/s │ │
│ ├─ 1000 2.69 µs │ 17.68 µs │ 2.719 µs │ 2.882 µs │ 100 │ 100
│ │ 371.6 Mitem/s │ 56.53 Mitem/s │ 367.6 Mitem/s │ 346.9 Mitem/s │ │
│ ╰─ 10000 20.52 µs │ 57.49 µs │ 21.38 µs │ 22.6 µs │ 100 │ 100
│ 487.2 Mitem/s │ 173.9 Mitem/s │ 467.5 Mitem/s │ 442.4 Mitem/s │ │
╰─ clip_mixed │ │ │ │ │
├─ 1 239.8 ns │ 440.6 ns │ 329.9 ns │ 334.2 ns │ 100 │ 1600
│ 4.168 Mitem/s │ 2.269 Mitem/s │ 3.03 Mitem/s │ 2.992 Mitem/s │ │
├─ 10 1.261 µs │ 3.492 µs │ 1.895 µs │ 1.91 µs │ 100 │ 400
│ 7.924 Mitem/s │ 2.862 Mitem/s │ 5.276 Mitem/s │ 5.234 Mitem/s │ │
├─ 100 13.6 µs │ 83.33 µs │ 17.75 µs │ 19.44 µs │ 100 │ 100
│ 7.35 Mitem/s │ 1.199 Mitem/s │ 5.631 Mitem/s │ 5.142 Mitem/s │ │
├─ 1000 141.2 µs │ 230.3 µs │ 152.2 µs │ 154 µs │ 100 │ 100
│ 7.081 Mitem/s │ 4.342 Mitem/s │ 6.567 Mitem/s │ 6.492 Mitem/s │ │
╰─ 10000 1.475 ms │ 1.835 ms │ 1.532 ms │ 1.553 ms │ 100 │ 100
6.777 Mitem/s │ 5.447 Mitem/s │ 6.524 Mitem/s │ 6.435 Mitem/s │ │

6 changes: 5 additions & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ repository.workspace = true
documentation.workspace = true

[features]
default = ["std"]
default = ["std", "bumpalo"]
# Use std fp functions, enable I/O and timing support.
std = ["fp"]
# Use fp functions from the libm crate.
Expand All @@ -32,9 +32,13 @@ mm = ["fp", "dep:micromath"]
# For internal use only.
fp = []

bumpalo = ["dep:bumpalo"]

[dependencies]
libm = { version = "0.2", optional = true }
micromath = { version = "2.1", optional = true }

bumpalo = { version = "3.19", features = ["collections"], optional = true }

[lints]
workspace = true
3 changes: 2 additions & 1 deletion core/examples/hello_tri.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use retrofire_core::prelude::*;
use retrofire_core::render::{Model, render, shader};
use retrofire_core::{prelude::*, util::*};

fn main() {
let verts = [
Expand Down Expand Up @@ -53,6 +53,7 @@ fn main() {
}
#[cfg(feature = "std")]
{
use retrofire_core::util::pnm;
pnm::save_ppm("triangle.ppm", framebuf).unwrap();
}
}
7 changes: 6 additions & 1 deletion core/src/geom/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ impl<A, B> Mesh<A, B> {
}

/// Returns a mesh with the faces and vertices of both `self` and `other`.
#[must_use]
pub fn merge(mut self, Self { faces, verts }: Self) -> Self {
let n = self.verts.len();
self.verts.extend(verts);
Expand All @@ -107,7 +108,7 @@ fn assert_indices_in_bounds(faces: &[Tri<usize>], len: usize) {
assert!(
vs.iter().all(|&j| j < len),
"vertex index out of bounds at faces[{i}]: {vs:?}"
)
);
}
}

Expand Down Expand Up @@ -164,6 +165,7 @@ impl<A> Builder<A> {
///
/// # Panics
/// If any of the vertex indices in `faces` ≥ `verts.len()`.
#[must_use]
pub fn build(self) -> Mesh<A> {
// Sanity checks done by new()
Mesh::new(self.mesh.faces, self.mesh.verts)
Expand All @@ -175,6 +177,7 @@ impl<A> Builder<A> {
///
/// This is an eager operation, that is, only vertices *currently*
/// added to the builder are transformed.
#[must_use]
pub fn transform(self, tf: &Mat4<Model, Model>) -> Self {
self.warp(|v| vertex(tf.apply(&v.pos), v.attrib))
}
Expand All @@ -184,6 +187,7 @@ impl<A> Builder<A> {
/// This method can be used for various nonlinear transformations such as
/// twisting or dilation. This is an eager operation, that is, only vertices
/// *currently* added to the builder are transformed.
#[must_use]
pub fn warp(mut self, f: impl FnMut(Vertex3<A>) -> Vertex3<A>) -> Self {
self.mesh.verts = self.mesh.verts.into_iter().map(f).collect();
self
Expand All @@ -202,6 +206,7 @@ impl<A> Builder<A> {
/// This is an eager operation, that is, only vertices *currently* added
/// to the builder are transformed. The attribute type of the result is
/// `Normal3`; the vertex type it accepts is changed accordingly.
#[must_use]
pub fn with_vertex_normals(self) -> Builder<Normal3> {
let Mesh { verts, faces } = self.mesh;

Expand Down
17 changes: 9 additions & 8 deletions core/src/geom/prim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ impl<B> Plane3<B> {
///
/// assert_eq!(<Plane3>::new(0.0, 0.0, 1.0, 2.0).project(pt), pt3(1.0, 2.0, 2.0));
/// ```
#[must_use]
pub fn project(&self, pt: Point3<B>) -> Point3<B> {
// The vector that projects pt on the plane is parallel with the plane
// normal and its length is the distance of pt from the plane.
Expand Down Expand Up @@ -672,9 +673,9 @@ impl<B> Line2<B> {
///
/// # Panics
/// If the vector (a, b) is not unit-length.
pub fn new(a: f32, b: f32, c: f32) -> Self {
pub const fn new(a: f32, b: f32, c: f32) -> Self {
// TODO This method can't itself normalize because const
assert!((a * a + b * b - 1.0).abs() < 1e-6, "non-unit normal");
assert!((a * a + b * b - 1.0).abs() < 1e-5, "non-unit normal",);
Self(Vector::new([a, b, -c]))
}

Expand Down Expand Up @@ -720,7 +721,7 @@ impl<B> Line2<B> {

/// Returns the coefficients [a, b, c] of the line equation ax + by = c.
pub const fn coeffs(&self) -> [f32; 3] {
return self.0.0;
self.0.0
}
}

Expand Down Expand Up @@ -1071,21 +1072,21 @@ mod tests {
let mut l: Line2;

l = Line2::new(1.0, 0.0, 0.0); // x = 0
assert_eq!(format!("{:?}", l), "Line(x = 0)");
assert_eq!(format!("{l:?}"), "Line(x = 0)");

l = Line2::from_points(pt2(2.0, 0.0), pt2(2.0, -1.0));
assert_eq!(l.coeffs(), [1.0, 0.0, -2.0]);
assert_eq!(format!("{:?}", l), "Line(x = 2)");
assert_eq!(format!("{l:?}"), "Line(x = 2)");

l = Line2::new(1.0, 0.0, 2.0); // x = 2
assert_eq!(format!("{:?}", l), "Line(x = 2)");
assert_eq!(format!("{l:?}"), "Line(x = 2)");

l = Line2::new(0.0, 1.0, 0.0); // y = 0
assert_eq!(format!("{:?}", l), "Line(y = 0)");
assert_eq!(format!("{l:?}"), "Line(y = 0)");

l = Line2::from_points(pt2(0.0, -3.0), pt2(1.0, -3.0)); // y = -3
assert_eq!(l.slope_intercept(), Some((0.0, -3.0)));
assert_eq!(format!("{:?}", l), "Line(y = -3)");
assert_eq!(format!("{l:?}"), "Line(y = -3)");

l = Line2::new(0.0, 1.0, -3.0); // y = -3
assert_eq!(format!("{:?}", l), "Line(y = -3)");
Expand Down
1 change: 1 addition & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
//! # Example
//!
//! ```
#![allow(clippy::needless_doctest_main)]
#![doc = include_str!("../examples/hello_tri.rs")]
//! ```

Expand Down
2 changes: 1 addition & 1 deletion core/src/math.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Linear algebra and other useful mathematics.
//!
//! Includes [vectors][self::vec], [matrices][mat], [colors][color],
//! [angles][angle], [Bezier splines][spline] and [pseudo-random numbers][rand],
//! [angles][angle], [splines][spline] and [pseudo-random numbers][rand],
//! as well as support for custom [varying][vary] types and utilities such as
//! approximate equality comparisons.
//!
Expand Down
Loading
Loading