#![allow(dead_code)]
#[derive(Clone, Copy, PartialEq)]
pub enum MeshShaderStage {
Task,
Mesh,
Pixel,
}
impl MeshShaderStage {
pub fn name(&self) -> &'static str {
match self {
MeshShaderStage::Task => "task",
MeshShaderStage::Mesh => "mesh",
MeshShaderStage::Pixel => "pixel",
}
}
}
pub struct MeshShaderProgram {
pub stage: MeshShaderStage,
pub entry_point: String,
pub source: String,
pub max_vertices: u32,
pub max_primitives: u32,
}
pub struct MeshShaderExport {
pub programs: Vec<MeshShaderProgram>,
pub amplification_factor: u32,
}
pub fn new_mesh_shader_export() -> MeshShaderExport {
MeshShaderExport {
programs: Vec::new(),
amplification_factor: 1,
}
}
#[allow(clippy::too_many_arguments)]
pub fn add_mesh_shader_program(
exp: &mut MeshShaderExport,
stage: MeshShaderStage,
entry: &str,
source: &str,
max_verts: u32,
max_prims: u32,
) {
exp.programs.push(MeshShaderProgram {
stage,
entry_point: entry.to_string(),
source: source.to_string(),
max_vertices: max_verts,
max_primitives: max_prims,
});
}
pub fn mesh_shader_program_count(exp: &MeshShaderExport) -> usize {
exp.programs.len()
}
pub fn find_mesh_shader_program(
exp: &MeshShaderExport,
stage: MeshShaderStage,
) -> Option<&MeshShaderProgram> {
exp.programs.iter().find(|p| p.stage == stage)
}
pub fn validate_mesh_shader_export(exp: &MeshShaderExport) -> bool {
find_mesh_shader_program(exp, MeshShaderStage::Mesh).is_some()
}
pub fn render_mesh_shader_summary(exp: &MeshShaderExport) -> String {
let stages: Vec<&str> = exp.programs.iter().map(|p| p.stage.name()).collect();
format!(
"MeshShader stages:[{}] amplification:{}",
stages.join(","),
exp.amplification_factor
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_export_empty() {
let exp = new_mesh_shader_export();
assert_eq!(mesh_shader_program_count(&exp), 0 );
}
#[test]
fn add_program_increments() {
let mut exp = new_mesh_shader_export();
add_mesh_shader_program(&mut exp, MeshShaderStage::Mesh, "MeshMain", "", 256, 256);
assert_eq!(mesh_shader_program_count(&exp), 1 );
}
#[test]
fn stage_name_correct() {
assert_eq!(MeshShaderStage::Task.name(), "task" );
}
#[test]
fn find_program_by_stage() {
let mut exp = new_mesh_shader_export();
add_mesh_shader_program(&mut exp, MeshShaderStage::Pixel, "PSMain", "", 0, 0);
assert!(find_mesh_shader_program(&exp, MeshShaderStage::Pixel).is_some() );
}
#[test]
fn find_missing_none() {
let exp = new_mesh_shader_export();
assert!(find_mesh_shader_program(&exp, MeshShaderStage::Task).is_none() );
}
#[test]
fn validate_needs_mesh_stage() {
let mut exp = new_mesh_shader_export();
assert!(!validate_mesh_shader_export(&exp) );
add_mesh_shader_program(&mut exp, MeshShaderStage::Mesh, "MeshMain", "", 64, 42);
assert!(validate_mesh_shader_export(&exp) );
}
#[test]
fn render_summary_contains_stage_names() {
let mut exp = new_mesh_shader_export();
add_mesh_shader_program(&mut exp, MeshShaderStage::Mesh, "m", "", 64, 64);
add_mesh_shader_program(&mut exp, MeshShaderStage::Pixel, "p", "", 0, 0);
let s = render_mesh_shader_summary(&exp);
assert!(s.contains("mesh") );
assert!(s.contains("pixel") );
}
#[test]
fn max_vertices_stored() {
let mut exp = new_mesh_shader_export();
add_mesh_shader_program(&mut exp, MeshShaderStage::Mesh, "m", "", 128, 84);
let p = find_mesh_shader_program(&exp, MeshShaderStage::Mesh).expect("should succeed");
assert_eq!(p.max_vertices, 128 );
}
#[test]
fn amplification_factor_default_one() {
let exp = new_mesh_shader_export();
assert_eq!(exp.amplification_factor, 1 );
}
}