cli(render): add ability to specify frame options

This commit is contained in:
chyyran 2024-09-26 23:35:17 -04:00 committed by Ronny Chan
parent 91f8089277
commit 84e78f4e48
10 changed files with 213 additions and 101 deletions

View file

@ -9,7 +9,7 @@ use librashader::reflect::semantics::ShaderSemantics;
use librashader::reflect::{CompileShader, FromCompilation, ReflectShader, SpirvCompilation}; use librashader::reflect::{CompileShader, FromCompilation, ReflectShader, SpirvCompilation};
use librashader::{FastHashMap, ShortString}; use librashader::{FastHashMap, ShortString};
use librashader_runtime::parameters::RuntimeParameters; use librashader_runtime::parameters::RuntimeParameters;
use librashader_test::render::RenderTest; use librashader_test::render::{CommonFrameOptions, RenderTest};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
/// Helpers and utilities to reflect and debug 'slang' shaders and presets. /// Helpers and utilities to reflect and debug 'slang' shaders and presets.
@ -20,34 +20,76 @@ struct Args {
command: Commands, command: Commands,
} }
#[derive(clap::Args, Debug)]
struct PresetArgs {
/// The path to the shader preset to load.
#[arg(short, long)]
preset: PathBuf,
/// Additional wildcard options, comma separated with equals signs. The PRESET and PRESET_DIR
/// wildcards are always added to the preset parsing context.
///
/// For example, CONTENT-DIR=MyVerticalGames,GAME=mspacman
#[arg(short, long, value_delimiter = ',', num_args = 1..)]
wildcards: Option<Vec<String>>,
}
#[derive(clap::Args, Debug)]
struct RenderArgs {
/// The frame to render.
#[arg(short, long, default_value_t = 60)]
frame: usize,
/// Parameters to pass to the shader preset, comma separated with equals signs.
///
/// For example, crt_gamma=2.5,halation_weight=0.001
#[arg(long, value_delimiter = ',', num_args = 1..)]
params: Option<Vec<String>>,
/// Set the number of passes enabled for the preset.
#[arg(long)]
passes_enabled: Option<usize>,
/// The path to the input image.
#[arg(short, long)]
image: PathBuf,
#[clap(flatten)]
options: Option<FrameOptionsArgs>,
}
impl From<FrameOptionsArgs> for CommonFrameOptions {
fn from(value: FrameOptionsArgs) -> Self {
Self {
clear_history: false,
frame_direction: value.frame_direction,
rotation: value.rotation,
total_subframes: value.total_subframes,
current_subframe: value.current_subframe,
}
}
}
#[derive(clap::Args, Debug)]
struct FrameOptionsArgs {
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
#[arg(long, default_value_t = 1, allow_hyphen_values = true)]
pub frame_direction: i32,
/// The rotation of the output. 0 = 0deg, 1 = 90deg, 2 = 180deg, 3 = 270deg.
#[arg(long, default_value_t = 0)]
pub rotation: u32,
/// The total number of subframes ran. Default is 1.
#[arg(long, default_value_t = 1)]
pub total_subframes: u32,
/// The current sub frame. Default is 1.
#[arg(long, default_value_t = 1)]
pub current_subframe: u32,
}
#[derive(Subcommand, Debug)] #[derive(Subcommand, Debug)]
enum Commands { enum Commands {
/// Render a shader preset against an image /// Render a shader preset against an image
Render { Render {
/// The frame to render. #[clap(flatten)]
#[arg(short, long, default_value_t = 60)] preset: PresetArgs,
frame: usize, #[clap(flatten)]
/// The path to the shader preset to load. render: RenderArgs,
#[arg(short, long)]
preset: PathBuf,
/// Additional wildcard options, comma separated with equals signs. The PRESET and PRESET_DIR
/// wildcards are always added to the preset parsing context.
///
/// For example, CONTENT-DIR=MyVerticalGames,GAME=mspacman
#[arg(short, long, value_delimiter = ',', num_args = 1..)]
wildcards: Option<Vec<String>>,
/// Parameters to pass to the shader preset, comma separated with equals signs.
///
/// For example, crt_gamma=2.5,halation_weight=0.001
#[arg(long, value_delimiter = ',', num_args = 1..)]
params: Option<Vec<String>>,
/// Set the number of passes enabled for the preset.
#[arg(long)]
passes_enabled: Option<usize>,
/// The path to the input image.
#[arg(short, long)]
image: PathBuf,
/// The path to the output image /// The path to the output image
/// ///
/// If `-`, writes the image in PNG format to stdout. /// If `-`, writes the image in PNG format to stdout.
@ -60,29 +102,10 @@ enum Commands {
/// Compare two runtimes and get a similarity score between the two /// Compare two runtimes and get a similarity score between the two
/// runtimes rendering the same frame /// runtimes rendering the same frame
Compare { Compare {
/// The frame to render. #[clap(flatten)]
#[arg(short, long, default_value_t = 60)] preset: PresetArgs,
frame: usize, #[clap(flatten)]
/// The path to the shader preset to load. render: RenderArgs,
#[arg(short, long)]
preset: PathBuf,
/// Additional wildcard options, comma separated with equals signs. The PRESET and PRESET_DIR
/// wildcards are always added to the preset parsing context.
///
/// For example, CONTENT-DIR=MyVerticalGames,GAME=mspacman
#[arg(short, long, value_delimiter = ',', num_args = 1..)]
wildcards: Option<Vec<String>>,
/// Parameters to pass to the shader preset, comma separated with equals signs.
///
/// For example, crt_gamma=2.5,halation_weight=0.001
#[arg(long, value_delimiter = ',', num_args = 1..)]
params: Option<Vec<String>>,
/// Set the number of passes enabled for the preset.
#[arg(long)]
passes_enabled: Option<usize>,
/// The path to the input image.
#[arg(short, long)]
image: PathBuf,
/// The runtime to compare against /// The runtime to compare against
#[arg(value_enum, short, long)] #[arg(value_enum, short, long)]
left: Runtime, left: Runtime,
@ -97,15 +120,8 @@ enum Commands {
}, },
/// Parse a preset and get a JSON representation of the data. /// Parse a preset and get a JSON representation of the data.
Parse { Parse {
/// The path to the shader preset to load. #[clap(flatten)]
#[arg(short, long)] preset: PresetArgs,
preset: PathBuf,
/// Additional wildcard options, comma separated with equals signs. The PRESET and PRESET_DIR
/// wildcards are always added to the preset parsing context.
///
/// For example, CONTENT-DIR=MyVerticalGames,GAME=mspacman
#[arg(short, long, value_delimiter = ',', num_args = 1..)]
wildcards: Option<Vec<String>>,
}, },
/// Get the raw GLSL output of a preprocessed shader. /// Get the raw GLSL output of a preprocessed shader.
Preprocess { Preprocess {
@ -146,15 +162,8 @@ enum Commands {
}, },
/// Reflect the shader relative to a preset, giving information about semantics used in a slang shader. /// Reflect the shader relative to a preset, giving information about semantics used in a slang shader.
Reflect { Reflect {
/// The path to the shader preset to load. #[clap(flatten)]
#[arg(short, long)] preset: PresetArgs,
preset: PathBuf,
/// Additional wildcard options, comma separated with equals signs. The PRESET and PRESET_DIR
/// wildcards are always added to the preset parsing context.
///
/// For example, CONTENT-DIR=MyVerticalGames,GAME=mspacman
#[arg(short, long, value_delimiter = ',', num_args = 1..)]
wildcards: Option<Vec<String>>,
/// The pass index to use. /// The pass index to use.
#[arg(short, long)] #[arg(short, long)]
@ -270,16 +279,22 @@ pub fn main() -> Result<(), anyhow::Error> {
match args.command { match args.command {
Commands::Render { Commands::Render {
frame,
preset, preset,
wildcards, render,
params,
passes_enabled,
image,
out, out,
runtime, runtime,
} => { } => {
let PresetArgs { preset, wildcards } = preset;
let RenderArgs {
frame,
params,
passes_enabled,
image,
options,
} = render;
let test: &mut dyn RenderTest = get_runtime!(runtime, image); let test: &mut dyn RenderTest = get_runtime!(runtime, image);
let preset = get_shader_preset(preset, wildcards)?; let preset = get_shader_preset(preset, wildcards)?;
let params = parse_params(params)?; let params = parse_params(params)?;
@ -287,6 +302,7 @@ pub fn main() -> Result<(), anyhow::Error> {
preset, preset,
frame, frame,
Some(&|rp| set_params(rp, &params, passes_enabled)), Some(&|rp| set_params(rp, &params, passes_enabled)),
options.map(CommonFrameOptions::from),
)?; )?;
if out.as_path() == Path::new("-") { if out.as_path() == Path::new("-") {
@ -297,18 +313,24 @@ pub fn main() -> Result<(), anyhow::Error> {
} }
} }
Commands::Compare { Commands::Compare {
frame,
preset, preset,
wildcards, render,
params,
passes_enabled,
image,
left, left,
right, right,
out, out,
} => { } => {
let PresetArgs { preset, wildcards } = preset;
let RenderArgs {
frame,
params,
passes_enabled,
image,
options,
} = render;
let left: &mut dyn RenderTest = get_runtime!(left, image); let left: &mut dyn RenderTest = get_runtime!(left, image);
let right: &mut dyn RenderTest = get_runtime!(right, image); let right: &mut dyn RenderTest = get_runtime!(right, image);
let params = parse_params(params)?; let params = parse_params(params)?;
let left_preset = get_shader_preset(preset.clone(), wildcards.clone())?; let left_preset = get_shader_preset(preset.clone(), wildcards.clone())?;
@ -316,6 +338,7 @@ pub fn main() -> Result<(), anyhow::Error> {
left_preset, left_preset,
frame, frame,
Some(&|rp| set_params(rp, &params, passes_enabled)), Some(&|rp| set_params(rp, &params, passes_enabled)),
None,
)?; )?;
let right_preset = get_shader_preset(preset.clone(), wildcards.clone())?; let right_preset = get_shader_preset(preset.clone(), wildcards.clone())?;
@ -323,6 +346,7 @@ pub fn main() -> Result<(), anyhow::Error> {
right_preset, right_preset,
frame, frame,
Some(&|rp| set_params(rp, &params, passes_enabled)), Some(&|rp| set_params(rp, &params, passes_enabled)),
options.map(CommonFrameOptions::from),
)?; )?;
let similarity = image_compare::rgba_hybrid_compare(&left_image, &right_image)?; let similarity = image_compare::rgba_hybrid_compare(&left_image, &right_image)?;
@ -338,7 +362,9 @@ pub fn main() -> Result<(), anyhow::Error> {
} }
} }
} }
Commands::Parse { preset, wildcards } => { Commands::Parse { preset } => {
let PresetArgs { preset, wildcards } = preset;
let preset = get_shader_preset(preset, wildcards)?; let preset = get_shader_preset(preset, wildcards)?;
let out = serde_json::to_string_pretty(&preset)?; let out = serde_json::to_string_pretty(&preset)?;
print!("{out:}"); print!("{out:}");
@ -451,10 +477,11 @@ pub fn main() -> Result<(), anyhow::Error> {
} }
Commands::Reflect { Commands::Reflect {
preset, preset,
wildcards,
index, index,
backend, backend,
} => { } => {
let PresetArgs { preset, wildcards } = preset;
let preset = get_shader_preset(preset, wildcards)?; let preset = get_shader_preset(preset, wildcards)?;
let Some(shader) = preset.shaders.get(index) else { let Some(shader) = preset.shaders.get(index) else {
return Err(anyhow!("Invalid pass index for the preset")); return Err(anyhow!("Invalid pass index for the preset"));

View file

@ -1,4 +1,4 @@
use crate::render::RenderTest; use crate::render::{CommonFrameOptions, RenderTest};
use anyhow::anyhow; use anyhow::anyhow;
use image::RgbaImage; use image::RgbaImage;
use librashader::runtime::d3d11::*; use librashader::runtime::d3d11::*;
@ -19,6 +19,7 @@ impl RenderTest for Direct3D11 {
preset: ShaderPreset, preset: ShaderPreset,
frame_count: usize, frame_count: usize,
param_setter: Option<&dyn Fn(&RuntimeParameters)>, param_setter: Option<&dyn Fn(&RuntimeParameters)>,
frame_options: Option<CommonFrameOptions>,
) -> anyhow::Result<image::RgbaImage> { ) -> anyhow::Result<image::RgbaImage> {
let (renderbuffer, rtv) = self.create_renderbuffer(self.image_bytes.size)?; let (renderbuffer, rtv) = self.create_renderbuffer(self.image_bytes.size)?;
@ -41,7 +42,15 @@ impl RenderTest for Direct3D11 {
&self.image_srv, &self.image_srv,
&Viewport::new_render_target_sized_origin(rtv, None)?, &Viewport::new_render_target_sized_origin(rtv, None)?,
frame_count, frame_count,
None, frame_options
.map(|options| FrameOptions {
clear_history: options.clear_history,
frame_direction: options.frame_direction,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
})
.as_ref(),
)?; )?;
let mut renderbuffer_desc = Default::default(); let mut renderbuffer_desc = Default::default();

View file

@ -2,13 +2,13 @@ mod descriptor_heap;
mod util; mod util;
use crate::render::d3d12::descriptor_heap::{CpuStagingHeap, RenderTargetHeap}; use crate::render::d3d12::descriptor_heap::{CpuStagingHeap, RenderTargetHeap};
use crate::render::RenderTest; use crate::render::{CommonFrameOptions, RenderTest};
use anyhow::anyhow; use anyhow::anyhow;
use d3d12_descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot}; use d3d12_descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot};
use image::RgbaImage; use image::RgbaImage;
use librashader::presets::ShaderPreset; use librashader::presets::ShaderPreset;
use librashader::runtime::d3d12::{ use librashader::runtime::d3d12::{
D3D12InputImage, D3D12OutputView, FilterChain, FilterChainOptions, D3D12InputImage, D3D12OutputView, FilterChain, FilterChainOptions, FrameOptions,
}; };
use librashader::runtime::Viewport; use librashader::runtime::Viewport;
use librashader::runtime::{FilterChainParameters, RuntimeParameters}; use librashader::runtime::{FilterChainParameters, RuntimeParameters};
@ -65,6 +65,7 @@ impl RenderTest for Direct3D12 {
preset: ShaderPreset, preset: ShaderPreset,
frame_count: usize, frame_count: usize,
param_setter: Option<&dyn Fn(&RuntimeParameters)>, param_setter: Option<&dyn Fn(&RuntimeParameters)>,
frame_options: Option<CommonFrameOptions>,
) -> anyhow::Result<image::RgbaImage> { ) -> anyhow::Result<image::RgbaImage> {
unsafe { unsafe {
let descriptor = self.rtv_heap.allocate_descriptor()?; let descriptor = self.rtv_heap.allocate_descriptor()?;
@ -145,7 +146,15 @@ impl RenderTest for Direct3D12 {
None, None,
)?, )?,
frame_count, frame_count,
None, frame_options
.map(|options| FrameOptions {
clear_history: options.clear_history,
frame_direction: options.frame_direction,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
})
.as_ref(),
)?; )?;
cmd.Close()?; cmd.Close()?;

View file

@ -1,8 +1,8 @@
use crate::render::RenderTest; use crate::render::{CommonFrameOptions, RenderTest};
use anyhow::anyhow; use anyhow::anyhow;
use image::RgbaImage; use image::RgbaImage;
use librashader::presets::ShaderPreset; use librashader::presets::ShaderPreset;
use librashader::runtime::d3d9::{FilterChain, FilterChainOptions}; use librashader::runtime::d3d9::{FilterChain, FilterChainOptions, FrameOptions};
use librashader::runtime::Viewport; use librashader::runtime::Viewport;
use librashader::runtime::{FilterChainParameters, RuntimeParameters}; use librashader::runtime::{FilterChainParameters, RuntimeParameters};
use librashader_runtime::image::{Image, PixelFormat, UVDirection, BGRA8}; use librashader_runtime::image::{Image, PixelFormat, UVDirection, BGRA8};
@ -36,6 +36,7 @@ impl RenderTest for Direct3D9 {
preset: ShaderPreset, preset: ShaderPreset,
frame_count: usize, frame_count: usize,
param_setter: Option<&dyn Fn(&RuntimeParameters)>, param_setter: Option<&dyn Fn(&RuntimeParameters)>,
frame_options: Option<CommonFrameOptions>,
) -> anyhow::Result<image::RgbaImage> { ) -> anyhow::Result<image::RgbaImage> {
unsafe { unsafe {
let mut filter_chain = FilterChain::load_from_preset( let mut filter_chain = FilterChain::load_from_preset(
@ -87,7 +88,15 @@ impl RenderTest for Direct3D9 {
&self.texture, &self.texture,
&Viewport::new_render_target_sized_origin(surface.clone(), None)?, &Viewport::new_render_target_sized_origin(surface.clone(), None)?,
frame_count, frame_count,
None, frame_options
.map(|options| FrameOptions {
clear_history: options.clear_history,
frame_direction: options.frame_direction,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
})
.as_ref(),
)?; )?;
self.device.GetRenderTargetData(&surface, &copy_texture)?; self.device.GetRenderTargetData(&surface, &copy_texture)?;

View file

@ -1,12 +1,12 @@
mod context; mod context;
use crate::render::gl::context::{GLVersion, GlfwContext}; use crate::render::gl::context::{GLVersion, GlfwContext};
use crate::render::RenderTest; use crate::render::{CommonFrameOptions, RenderTest};
use anyhow::anyhow; use anyhow::anyhow;
use glow::{HasContext, PixelPackData, PixelUnpackData}; use glow::{HasContext, PixelPackData, PixelUnpackData};
use image::RgbaImage; use image::RgbaImage;
use librashader::presets::ShaderPreset; use librashader::presets::ShaderPreset;
use librashader::runtime::gl::{FilterChain, FilterChainOptions, GLImage}; use librashader::runtime::gl::{FilterChain, FilterChainOptions, FrameOptions, GLImage};
use librashader::runtime::Viewport; use librashader::runtime::Viewport;
use librashader::runtime::{FilterChainParameters, RuntimeParameters}; use librashader::runtime::{FilterChainParameters, RuntimeParameters};
use librashader_runtime::image::{Image, UVDirection, RGBA8}; use librashader_runtime::image::{Image, UVDirection, RGBA8};
@ -35,6 +35,7 @@ impl RenderTest for OpenGl3 {
preset: ShaderPreset, preset: ShaderPreset,
frame_count: usize, frame_count: usize,
param_setter: Option<&dyn Fn(&RuntimeParameters)>, param_setter: Option<&dyn Fn(&RuntimeParameters)>,
frame_options: Option<CommonFrameOptions>,
) -> anyhow::Result<image::RgbaImage> { ) -> anyhow::Result<image::RgbaImage> {
let mut filter_chain = unsafe { let mut filter_chain = unsafe {
FilterChain::load_from_preset( FilterChain::load_from_preset(
@ -53,7 +54,19 @@ impl RenderTest for OpenGl3 {
setter(filter_chain.parameters()); setter(filter_chain.parameters());
} }
Ok(self.0.render(&mut filter_chain, frame_count)?) Ok(self.0.render(
&mut filter_chain,
frame_count,
frame_options
.map(|options| FrameOptions {
clear_history: options.clear_history,
frame_direction: options.frame_direction,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
})
.as_ref(),
)?)
} }
} }
@ -70,6 +83,7 @@ impl RenderTest for OpenGl4 {
preset: ShaderPreset, preset: ShaderPreset,
frame_count: usize, frame_count: usize,
param_setter: Option<&dyn Fn(&RuntimeParameters)>, param_setter: Option<&dyn Fn(&RuntimeParameters)>,
frame_options: Option<CommonFrameOptions>,
) -> anyhow::Result<image::RgbaImage> { ) -> anyhow::Result<image::RgbaImage> {
let mut filter_chain = unsafe { let mut filter_chain = unsafe {
FilterChain::load_from_preset( FilterChain::load_from_preset(
@ -88,7 +102,19 @@ impl RenderTest for OpenGl4 {
setter(filter_chain.parameters()); setter(filter_chain.parameters());
} }
Ok(self.0.render(&mut filter_chain, frame_count)?) Ok(self.0.render(
&mut filter_chain,
frame_count,
frame_options
.map(|options| FrameOptions {
clear_history: options.clear_history,
frame_direction: options.frame_direction,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
})
.as_ref(),
)?)
} }
} }
@ -163,6 +189,7 @@ impl OpenGl {
&self, &self,
chain: &mut FilterChain, chain: &mut FilterChain,
frame_count: usize, frame_count: usize,
options: Option<&FrameOptions>,
) -> Result<RgbaImage, anyhow::Error> { ) -> Result<RgbaImage, anyhow::Error> {
let render_texture = unsafe { let render_texture = unsafe {
let tex = self let tex = self
@ -193,7 +220,7 @@ impl OpenGl {
&self.texture, &self.texture,
&Viewport::new_render_target_sized_origin(&output, None)?, &Viewport::new_render_target_sized_origin(&output, None)?,
frame_count, frame_count,
None, options,
)?; )?;
} }

View file

@ -20,6 +20,7 @@ pub mod wgpu;
pub mod mtl; pub mod mtl;
use librashader::presets::ShaderPreset; use librashader::presets::ShaderPreset;
use librashader_runtime::impl_default_frame_options;
use librashader_runtime::parameters::RuntimeParameters; use librashader_runtime::parameters::RuntimeParameters;
use std::path::Path; use std::path::Path;
@ -56,7 +57,7 @@ pub trait RenderTest {
preset: ShaderPreset, preset: ShaderPreset,
frame_count: usize, frame_count: usize,
) -> anyhow::Result<image::RgbaImage> { ) -> anyhow::Result<image::RgbaImage> {
self.render_with_preset_and_params(preset, frame_count, None) self.render_with_preset_and_params(preset, frame_count, None, None)
} }
/// Render a shader onto an image buffer, applying the provided shader. /// Render a shader onto an image buffer, applying the provided shader.
@ -72,9 +73,12 @@ pub trait RenderTest {
preset: ShaderPreset, preset: ShaderPreset,
frame_count: usize, frame_count: usize,
param_setter: Option<&dyn Fn(&RuntimeParameters)>, param_setter: Option<&dyn Fn(&RuntimeParameters)>,
frame_options: Option<CommonFrameOptions>,
) -> anyhow::Result<image::RgbaImage>; ) -> anyhow::Result<image::RgbaImage>;
} }
impl_default_frame_options!(CommonFrameOptions);
#[cfg(test)] #[cfg(test)]
mod test { mod test {

View file

@ -1,8 +1,8 @@
use crate::render::RenderTest; use crate::render::{CommonFrameOptions, RenderTest};
use anyhow::anyhow; use anyhow::anyhow;
use image::RgbaImage; use image::RgbaImage;
use librashader::presets::ShaderPreset; use librashader::presets::ShaderPreset;
use librashader::runtime::mtl::{FilterChain, FilterChainOptions}; use librashader::runtime::mtl::{FilterChain, FilterChainOptions, FrameOptions};
use librashader::runtime::Viewport; use librashader::runtime::Viewport;
use librashader::runtime::{FilterChainParameters, RuntimeParameters}; use librashader::runtime::{FilterChainParameters, RuntimeParameters};
use librashader_runtime::image::{Image, PixelFormat, UVDirection, BGRA8, RGBA8}; use librashader_runtime::image::{Image, PixelFormat, UVDirection, BGRA8, RGBA8};
@ -36,6 +36,7 @@ impl RenderTest for Metal {
preset: ShaderPreset, preset: ShaderPreset,
frame_count: usize, frame_count: usize,
param_setter: Option<&dyn Fn(&RuntimeParameters)>, param_setter: Option<&dyn Fn(&RuntimeParameters)>,
frame_options: Option<CommonFrameOptions>,
) -> anyhow::Result<image::RgbaImage> { ) -> anyhow::Result<image::RgbaImage> {
let queue = self let queue = self
.device .device
@ -90,7 +91,15 @@ impl RenderTest for Metal {
&Viewport::new_render_target_sized_origin(render_texture.as_ref(), None)?, &Viewport::new_render_target_sized_origin(render_texture.as_ref(), None)?,
cmd.as_ref(), cmd.as_ref(),
frame_count, frame_count,
None, frame_options
.map(|options| FrameOptions {
clear_history: options.clear_history,
frame_direction: options.frame_direction,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
})
.as_ref(),
)?; )?;
cmd.commit(); cmd.commit();

View file

@ -1,12 +1,12 @@
use crate::render::vk::base::VulkanBase; use crate::render::vk::base::VulkanBase;
use crate::render::vk::memory::{VulkanBuffer, VulkanImageMemory}; use crate::render::vk::memory::{VulkanBuffer, VulkanImageMemory};
use crate::render::RenderTest; use crate::render::{CommonFrameOptions, RenderTest};
use anyhow::anyhow; use anyhow::anyhow;
use ash::vk; use ash::vk;
use gpu_allocator::MemoryLocation; use gpu_allocator::MemoryLocation;
use image::RgbaImage; use image::RgbaImage;
use librashader::presets::ShaderPreset; use librashader::presets::ShaderPreset;
use librashader::runtime::vk::{FilterChain, FilterChainOptions, VulkanImage}; use librashader::runtime::vk::{FilterChain, FilterChainOptions, FrameOptions, VulkanImage};
use librashader::runtime::Viewport; use librashader::runtime::Viewport;
use librashader::runtime::{FilterChainParameters, RuntimeParameters}; use librashader::runtime::{FilterChainParameters, RuntimeParameters};
use librashader_runtime::image::{Image, UVDirection, BGRA8}; use librashader_runtime::image::{Image, UVDirection, BGRA8};
@ -37,6 +37,7 @@ impl RenderTest for Vulkan {
preset: ShaderPreset, preset: ShaderPreset,
frame_count: usize, frame_count: usize,
param_setter: Option<&dyn Fn(&RuntimeParameters)>, param_setter: Option<&dyn Fn(&RuntimeParameters)>,
frame_options: Option<CommonFrameOptions>,
) -> anyhow::Result<image::RgbaImage> { ) -> anyhow::Result<image::RgbaImage> {
unsafe { unsafe {
let mut filter_chain = FilterChain::load_from_preset( let mut filter_chain = FilterChain::load_from_preset(
@ -157,7 +158,15 @@ impl RenderTest for Vulkan {
)?, )?,
cmd, cmd,
frame_count, frame_count,
None, frame_options
.map(|options| FrameOptions {
clear_history: options.clear_history,
frame_direction: options.frame_direction,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
})
.as_ref(),
)?; )?;
{ {

View file

@ -1,4 +1,4 @@
use crate::render::RenderTest; use crate::render::{CommonFrameOptions, RenderTest};
use anyhow::anyhow; use anyhow::anyhow;
use image::RgbaImage; use image::RgbaImage;
use librashader::runtime::wgpu::*; use librashader::runtime::wgpu::*;
@ -61,6 +61,7 @@ impl RenderTest for Wgpu {
preset: ShaderPreset, preset: ShaderPreset,
frame_count: usize, frame_count: usize,
param_setter: Option<&dyn Fn(&RuntimeParameters)>, param_setter: Option<&dyn Fn(&RuntimeParameters)>,
frame_options: Option<CommonFrameOptions>,
) -> anyhow::Result<image::RgbaImage> { ) -> anyhow::Result<image::RgbaImage> {
let mut chain = FilterChain::load_from_preset( let mut chain = FilterChain::load_from_preset(
preset, preset,
@ -112,7 +113,15 @@ impl RenderTest for Wgpu {
&Viewport::new_render_target_sized_origin(output, None)?, &Viewport::new_render_target_sized_origin(output, None)?,
&mut cmd, &mut cmd,
frame_count, frame_count,
None, frame_options
.map(|options| FrameOptions {
clear_history: options.clear_history,
frame_direction: options.frame_direction,
rotation: options.rotation,
total_subframes: options.total_subframes,
current_subframe: options.current_subframe,
})
.as_ref(),
)?; )?;
cmd.copy_texture_to_buffer( cmd.copy_texture_to_buffer(

View file

@ -466,7 +466,7 @@ macro_rules! impl_default_frame_options {
pub rotation: u32, pub rotation: u32,
/// The total number of subframes ran. Default is 1. /// The total number of subframes ran. Default is 1.
pub total_subframes: u32, pub total_subframes: u32,
// The current sub frame. Default is 1. /// The current sub frame. Default is 1.
pub current_subframe: u32, pub current_subframe: u32,
} }