Skip to content

Commit

Permalink
Better API lifetimes, fixed MSAA bug
Browse files Browse the repository at this point in the history
  • Loading branch information
zesterer committed Nov 2, 2023
1 parent bca24bd commit 15836dd
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 43 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
// You can add fields to this type, like uniforms in traditional GPU shader programs.
struct Triangle;

impl Pipeline for Triangle {
type Vertex<'v> = [f32; 2]; // Each vertex has an x and y component
impl<'r> Pipeline<'r> for Triangle {
type Vertex = [f32; 2]; // Each vertex has an x and y component
type VertexData = Unit; // No data is passed from the vertex shader to the fragment shader
type Primitives = TriangleList; // Our vertices come in the form of a list of triangles
type Fragment = [u8; 3]; // Each fragment is 3 bytes: red, green, and blue
Expand Down
6 changes: 3 additions & 3 deletions examples/spinning_cube.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ struct Cube {
mvp: Mat4<f32>,
}

impl Pipeline for Cube {
type Vertex<'v> = (Vec4<f32>, Rgba<f32>);
impl<'r> Pipeline<'r> for Cube {
type Vertex = (Vec4<f32>, Rgba<f32>);
type VertexData = Rgba<f32>;
type Primitives = TriangleList;
type Pixel = u32;
type Fragment = Rgba<f32>;

#[inline(always)]
fn vertex(&self, (pos, color): &Self::Vertex<'_>) -> ([f32; 4], Self::VertexData) {
fn vertex(&self, (pos, color): &Self::Vertex) -> ([f32; 4], Self::VertexData) {
((self.mvp * *pos).into_array(), *color)
}

Expand Down
16 changes: 8 additions & 8 deletions examples/teapot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ struct TeapotShadow {
mvp: Mat4<f32>,
}

impl Pipeline for TeapotShadow {
type Vertex<'v> = wavefront::Vertex<'v>;
impl<'r> Pipeline<'r> for TeapotShadow {
type Vertex = wavefront::Vertex<'r>;
type VertexData = f32;
type Primitives = TriangleList;
type Fragment = Unit;
Expand All @@ -33,7 +33,7 @@ impl Pipeline for TeapotShadow {
}

#[inline(always)]
fn vertex(&self, vertex: &Self::Vertex<'_>) -> ([f32; 4], Self::VertexData) {
fn vertex(&self, vertex: &Self::Vertex) -> ([f32; 4], Self::VertexData) {
(
(self.mvp * Vec4::from_point(Vec3::from(vertex.position()))).into_array(),
0.0,
Expand All @@ -49,12 +49,12 @@ impl Pipeline for TeapotShadow {
fn blend(&self, _old: Self::Pixel, _new: Self::Fragment) {}
}

struct Teapot<'a> {
struct Teapot<'r> {
m: Mat4<f32>,
v: Mat4<f32>,
p: Mat4<f32>,
light_pos: Vec3<f32>,
shadow: Clamped<Linear<&'a Buffer2d<f32>>>,
shadow: Clamped<Linear<&'r Buffer2d<f32>>>,
light_vp: Mat4<f32>,
}

Expand All @@ -65,8 +65,8 @@ struct VertexData {
light_view_pos: Vec3<f32>,
}

impl<'a> Pipeline for Teapot<'a> {
type Vertex<'v> = wavefront::Vertex<'v>;
impl<'r> Pipeline<'r> for Teapot<'r> {
type Vertex = wavefront::Vertex<'r>;
type VertexData = VertexData;
type Primitives = TriangleList;
type Fragment = Rgba<f32>;
Expand All @@ -78,7 +78,7 @@ impl<'a> Pipeline for Teapot<'a> {
}

#[inline(always)]
fn vertex(&self, vertex: &Self::Vertex<'_>) -> ([f32; 4], Self::VertexData) {
fn vertex(&self, vertex: &Self::Vertex) -> ([f32; 4], Self::VertexData) {
let wpos = self.m * Vec4::from_point(Vec3::from(vertex.position()));
let wnorm = self.m * Vec4::from_direction(-Vec3::from(vertex.normal().unwrap()));

Expand Down
18 changes: 11 additions & 7 deletions examples/texture_mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,26 @@ use image::RgbaImage;
use minifb::{Key, Window, WindowOptions};
use vek::{Mat4, Rgba, Vec2, Vec3, Vec4};

struct Cube<'a> {
struct Cube<'r> {
mvp: Mat4<f32>,
positions: &'a [Vec4<f32>],
uvs: &'a [Vec2<f32>],
sampler: &'a Nearest<RgbaImage>,
positions: &'r [Vec4<f32>],
uvs: &'r [Vec2<f32>],
sampler: &'r Nearest<RgbaImage>,
}

impl<'a> Pipeline for Cube<'a> {
type Vertex<'v> = usize;
impl<'r> Pipeline<'r> for Cube<'r> {
type Vertex = usize;
type VertexData = Vec2<f32>;
type Primitives = TriangleList;
type Fragment = Rgba<f32>;
type Pixel = u32;

fn aa_mode(&self) -> euc::AaMode {
euc::AaMode::Msaa { level: 4 }
}

#[inline]
fn vertex(&self, v_index: &Self::Vertex<'_>) -> ([f32; 4], Self::VertexData) {
fn vertex(&self, v_index: &Self::Vertex) -> ([f32; 4], Self::VertexData) {
(
(self.mvp * self.positions[*v_index]).into_array(),
self.uvs[*v_index],
Expand Down
6 changes: 3 additions & 3 deletions examples/triangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use vek::*;

struct Triangle;

impl Pipeline for Triangle {
type Vertex<'v> = ([f32; 2], Rgba<f32>);
impl<'r> Pipeline<'r> for Triangle {
type Vertex = ([f32; 2], Rgba<f32>);
type VertexData = Rgba<f32>;
type Primitives = TriangleList;
type Fragment = Rgba<f32>;
type Pixel = u32;

fn vertex(&self, (pos, col): &Self::Vertex<'_>) -> ([f32; 4], Self::VertexData) {
fn vertex(&self, (pos, col): &Self::Vertex) -> ([f32; 4], Self::VertexData) {
([pos[0], pos[1], 0.0, 1.0], *col)
}

Expand Down
6 changes: 3 additions & 3 deletions examples/wireframes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ struct Teapot {
p: Mat4<f32>,
}

impl Pipeline for Teapot {
type Vertex<'v> = wavefront::Vertex<'v>;
impl<'r> Pipeline<'r> for Teapot {
type Vertex = wavefront::Vertex<'r>;
type VertexData = Unit;
type Primitives = LineTriangleList;
type Fragment = Rgba<f32>;
type Pixel = u32;

#[inline(always)]
fn vertex(&self, vertex: &Self::Vertex<'_>) -> ([f32; 4], Self::VertexData) {
fn vertex(&self, vertex: &Self::Vertex) -> ([f32; 4], Self::VertexData) {
let wpos = self.m * Vec4::from_point(Vec3::from(vertex.position()));

((self.p * (self.v * wpos)).into_array(), Unit)
Expand Down
34 changes: 17 additions & 17 deletions src/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ impl Default for CoordinateMode {
///
/// Additional methods such as [`Pipeline::depth_mode`], [Pipeline::`cull_mode`], etc. may be implemented to customize
/// the behaviour of the pipeline even further.
pub trait Pipeline: Sized {
type Vertex<'a>;
pub trait Pipeline<'r>: Sized {
type Vertex;
type VertexData: Clone + WeightedSum + Send + Sync;
type Primitives: PrimitiveKind<Self::VertexData>;
type Fragment: Clone + WeightedSum;
Expand Down Expand Up @@ -200,7 +200,7 @@ pub trait Pipeline: Sized {
/// [`Pipeline::VertexData`] to be interpolated and passed to the fragment shader.
///
/// This stage is executed at the beginning of pipeline execution.
fn vertex(&self, vertex: &Self::Vertex<'_>) -> ([f32; 4], Self::VertexData);
fn vertex(&self, vertex: &Self::Vertex) -> ([f32; 4], Self::VertexData);

/// Turn a primitive into many primitives.
///
Expand Down Expand Up @@ -233,11 +233,11 @@ pub trait Pipeline: Sized {
/// Render a stream of vertices to given provided pixel target and depth target using the rasterizer.
///
/// **Do not implement this method**
fn render<'a, S, V, P, D>(&self, vertices: S, pixel: &mut P, depth: &mut D)
fn render<S, V, P, D>(&self, vertices: S, pixel: &mut P, depth: &mut D)
where
Self: Send + Sync,
S: IntoIterator<Item = V>,
V: Borrow<Self::Vertex<'a>>,
V: Borrow<Self::Vertex>,
P: Target<Texel = Self::Pixel> + Send + Sync,
D: Target<Texel = f32> + Send + Sync,
{
Expand Down Expand Up @@ -290,15 +290,15 @@ pub trait Pipeline: Sized {
}

#[cfg(feature = "par")]
fn render_par<Pipe, S, P, D>(
fn render_par<'r, Pipe, S, P, D>(
pipeline: &Pipe,
fetch_vertex: S,
tgt_size: [usize; 2],
pixel: &mut P,
depth: &mut D,
msaa_level: usize,
) where
Pipe: Pipeline + Send + Sync,
Pipe: Pipeline<'r> + Send + Sync,
S: Iterator<Item = ([f32; 4], Pipe::VertexData)>,
P: Target<Texel = Pipe::Pixel> + Send + Sync,
D: Target<Texel = f32> + Send + Sync,
Expand All @@ -312,7 +312,7 @@ fn render_par<Pipe, S, P, D>(
let row = AtomicUsize::new(0);

const FRAGMENTS_PER_GROUP: usize = 20_000; // Magic number, maybe make this configurable?
let group_rows = FRAGMENTS_PER_GROUP * (msaa_level + 1) / tgt_size[0].max(1);
let group_rows = FRAGMENTS_PER_GROUP * (1 << msaa_level) / tgt_size[0].max(1);
let needed_threads = (tgt_size[1] / group_rows).min(threads);

let vertices = &vertices;
Expand Down Expand Up @@ -353,15 +353,15 @@ fn render_par<Pipe, S, P, D>(
}

#[cfg(not(feature = "par"))]
fn render_seq<Pipe, S, P, D>(
fn render_seq<'r, Pipe, S, P, D>(
pipeline: &Pipe,
fetch_vertex: S,
tgt_size: [usize; 2],
pixel: &mut P,
depth: &mut D,
msaa_level: usize,
) where
Pipe: Pipeline + Send + Sync,
Pipe: Pipeline<'r> + Send + Sync,
S: Iterator<Item = ([f32; 4], Pipe::VertexData)>,
P: Target<Texel = Pipe::Pixel> + Send + Sync,
D: Target<Texel = f32> + Send + Sync,
Expand All @@ -381,7 +381,7 @@ fn render_seq<Pipe, S, P, D>(
}
}

unsafe fn render_inner<Pipe, S, P, D>(
unsafe fn render_inner<'r, Pipe, S, P, D>(
pipeline: &Pipe,
fetch_vertex: S,
(tgt_min, tgt_max): ([usize; 2], [usize; 2]),
Expand All @@ -390,7 +390,7 @@ unsafe fn render_inner<Pipe, S, P, D>(
depth: &D,
msaa_level: usize,
) where
Pipe: Pipeline + Send + Sync,
Pipe: Pipeline<'r> + Send + Sync,
S: Iterator<Item = ([f32; 4], Pipe::VertexData)>,
P: Target<Texel = Pipe::Pixel> + Send + Sync,
D: Target<Texel = f32> + Send + Sync,
Expand Down Expand Up @@ -437,7 +437,7 @@ unsafe fn render_inner<Pipe, S, P, D>(

use crate::rasterizer::Blitter;

struct BlitterImpl<'a, Pipe: Pipeline, P, D> {
struct BlitterImpl<'a, 'r, Pipe: Pipeline<'r>, P, D> {
write_pixels: bool,
depth_mode: DepthMode,

Expand All @@ -454,9 +454,9 @@ unsafe fn render_inner<Pipe, S, P, D>(
msaa_buf: Option<Buffer2d<(u64, Option<Pipe::Fragment>)>>,
}

impl<'a, Pipe, P, D> BlitterImpl<'a, Pipe, P, D>
impl<'a, 'r, Pipe, P, D> BlitterImpl<'a, 'r, Pipe, P, D>
where
Pipe: Pipeline + Send + Sync,
Pipe: Pipeline<'r> + Send + Sync,
P: Target<Texel = Pipe::Pixel> + Send + Sync,
D: Target<Texel = f32> + Send + Sync,
{
Expand Down Expand Up @@ -484,9 +484,9 @@ unsafe fn render_inner<Pipe, S, P, D>(
}
}

impl<'a, Pipe, P, D> Blitter<Pipe::VertexData> for BlitterImpl<'a, Pipe, P, D>
impl<'a, 'r, Pipe, P, D> Blitter<Pipe::VertexData> for BlitterImpl<'a, 'r, Pipe, P, D>
where
Pipe: Pipeline + Send + Sync,
Pipe: Pipeline<'r> + Send + Sync,
P: Target<Texel = Pipe::Pixel> + Send + Sync,
D: Target<Texel = f32> + Send + Sync,
{
Expand Down

0 comments on commit 15836dd

Please sign in to comment.