test: abstract test framework

This commit is contained in:
chyyran 2024-09-24 17:58:16 -04:00 committed by Ronny Chan
parent 799d409ddb
commit 20039b9347
5 changed files with 62 additions and 39 deletions

View file

@ -6,6 +6,13 @@ use librashader::runtime::{Size, Viewport};
use std::path::Path; use std::path::Path;
impl RenderTest for Direct3D11 { impl RenderTest for Direct3D11 {
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
where
Self: Sized,
{
Direct3D11::new(path)
}
fn render(&self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> { fn render(&self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
let (renderbuffer, rtv) = self.create_renderbuffer(self.image_bytes.size)?; let (renderbuffer, rtv) = self.create_renderbuffer(self.image_bytes.size)?;

View file

@ -22,6 +22,13 @@ pub struct OpenGl3(OpenGl);
pub struct OpenGl4(OpenGl); pub struct OpenGl4(OpenGl);
impl RenderTest for OpenGl3 { impl RenderTest for OpenGl3 {
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
where
Self: Sized,
{
OpenGl3::new(path)
}
fn render(&self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> { fn render(&self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
let mut filter_chain = unsafe { let mut filter_chain = unsafe {
FilterChain::load_from_path( FilterChain::load_from_path(
@ -41,6 +48,13 @@ impl RenderTest for OpenGl3 {
} }
impl RenderTest for OpenGl4 { impl RenderTest for OpenGl4 {
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
where
Self: Sized,
{
OpenGl4::new(path)
}
fn render(&self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> { fn render(&self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
let mut filter_chain = unsafe { let mut filter_chain = unsafe {
FilterChain::load_from_path( FilterChain::load_from_path(

View file

@ -7,6 +7,11 @@ use std::path::Path;
/// Test harness to set up a device, render a triangle, and apply a shader /// Test harness to set up a device, render a triangle, and apply a shader
pub trait RenderTest { pub trait RenderTest {
/// Create a new instance of the test harness.
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
where
Self: Sized;
/// Render a shader onto an image buffer, applying the provided shader. /// Render a shader onto an image buffer, applying the provided shader.
/// ///
/// The test should render in linear colour space for proper comparison against /// The test should render in linear colour space for proper comparison against
@ -24,6 +29,10 @@ pub trait RenderTest {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::render::d3d11::Direct3D11;
use crate::render::gl::{OpenGl3, OpenGl4};
use crate::render::vk::Vulkan;
use crate::render::wgpu::Wgpu;
use crate::render::RenderTest; use crate::render::RenderTest;
use image::codecs::png::PngEncoder; use image::codecs::png::PngEncoder;
use std::fs::File; use std::fs::File;
@ -34,70 +43,49 @@ mod test {
// const FILTER_PATH: &str = // const FILTER_PATH: &str =
// "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp"; // "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp";
#[test] fn do_test<T: RenderTest>() -> anyhow::Result<()> {
pub fn test_d3d11() -> anyhow::Result<()> { let test = T::new(IMAGE_PATH)?;
let d3d11 = super::d3d11::Direct3D11::new(IMAGE_PATH)?; let image = test.render(FILTER_PATH, 100)?;
let image = d3d11.render(FILTER_PATH, 100)?;
let out = File::create("out.png")?; let out = File::create("out.png")?;
image.write_with_encoder(PngEncoder::new(out))?; image.write_with_encoder(PngEncoder::new(out))?;
Ok(()) Ok(())
} }
#[test]
pub fn test_d3d11() -> anyhow::Result<()> {
do_test::<Direct3D11>()
}
#[test] #[test]
pub fn test_wgpu() -> anyhow::Result<()> { pub fn test_wgpu() -> anyhow::Result<()> {
let wgpu = super::wgpu::Wgpu::new(IMAGE_PATH)?; do_test::<Wgpu>()
let image = wgpu.render(FILTER_PATH, 100)?;
let out = File::create("out.png")?;
image.write_with_encoder(PngEncoder::new(out))?;
Ok(())
} }
#[test] #[test]
pub fn test_vk() -> anyhow::Result<()> { pub fn test_vk() -> anyhow::Result<()> {
let vulkan = super::vk::Vulkan::new(IMAGE_PATH)?; do_test::<Vulkan>()
let image = vulkan.render(FILTER_PATH, 100)?;
//
let out = File::create("out.png")?;
image.write_with_encoder(PngEncoder::new(out))?;
Ok(())
} }
#[test] #[test]
pub fn test_gl3() -> anyhow::Result<()> { pub fn test_gl3() -> anyhow::Result<()> {
do_test::<OpenGl3>()
let gl = super::gl::OpenGl3::new(IMAGE_PATH)?;
let image = gl.render(FILTER_PATH, 1000)?;
let out = File::create("out.png")?;
image.write_with_encoder(PngEncoder::new(out))?;
Ok(())
} }
#[test] #[test]
pub fn test_gl4() -> anyhow::Result<()> { pub fn test_gl4() -> anyhow::Result<()> {
do_test::<OpenGl4>()
let gl = super::gl::OpenGl4::new(IMAGE_PATH)?;
let image = gl.render(FILTER_PATH, 1000)?;
let out = File::create("out.png")?;
image.write_with_encoder(PngEncoder::new(out))?;
Ok(())
} }
#[test] pub fn compare<A: RenderTest, B: RenderTest>() -> anyhow::Result<()> {
pub fn compare() -> anyhow::Result<()> { let a = A::new(IMAGE_PATH)?;
let d3d11 = super::d3d11::Direct3D11::new(IMAGE_PATH)?; let b = B::new(IMAGE_PATH)?;
let wgpu = super::wgpu::Wgpu::new(IMAGE_PATH)?;
let wgpu_image = wgpu.render(FILTER_PATH, 100)?; let a_image = a.render(FILTER_PATH, 100)?;
let d3d11_image = d3d11.render(FILTER_PATH, 100)?; let b_image = b.render(FILTER_PATH, 100)?;
let similarity = image_compare::rgba_hybrid_compare(&wgpu_image, &d3d11_image)?;
let similarity = image_compare::rgba_hybrid_compare(&a_image, &b_image)?;
assert!(similarity.score > 0.95); assert!(similarity.score > 0.95);
Ok(()) Ok(())
} }
} }

View file

@ -25,6 +25,13 @@ pub struct Vulkan {
} }
impl RenderTest for Vulkan { impl RenderTest for Vulkan {
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
where
Self: Sized,
{
Vulkan::new(path)
}
fn render(&self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> { fn render(&self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
unsafe { unsafe {
let mut filter_chain = FilterChain::load_from_path( let mut filter_chain = FilterChain::load_from_path(

View file

@ -49,6 +49,13 @@ impl BufferDimensions {
} }
impl RenderTest for Wgpu { impl RenderTest for Wgpu {
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
where
Self: Sized,
{
Wgpu::new(path)
}
fn render(&self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> { fn render(&self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
let mut chain = FilterChain::load_from_path( let mut chain = FilterChain::load_from_path(
path, path,