cli(render): add ability to specify params and passes enabled
This commit is contained in:
parent
3993f57271
commit
91f8089277
29
CLI.md
29
CLI.md
|
@ -46,6 +46,19 @@ Options:
|
|||
-p, --preset <PRESET>
|
||||
The path to the shader preset to load
|
||||
|
||||
-w, --wildcards <WILDCARDS>...
|
||||
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
|
||||
|
||||
--params <PARAMS>...
|
||||
Parameters to pass to the shader preset, comma separated with equals signs.
|
||||
|
||||
For example, crt_gamma=2.5,halation_weight=0.001
|
||||
|
||||
--passes-enabled <PASSES_ENABLED>
|
||||
Set the number of passes enabled for the preset
|
||||
|
||||
-i, --image <IMAGE>
|
||||
The path to the input image
|
||||
|
||||
|
@ -57,10 +70,11 @@ Options:
|
|||
-r, --runtime <RUNTIME>
|
||||
The runtime to use to render the shader preset
|
||||
|
||||
[possible values: opengl3, opengl4, vulkan, wgpu, d3d9, d3d11, d3d12, metal]
|
||||
[possible values: opengl3, opengl4, vulkan, wgpu, d3d9, d3d11, d3d12]
|
||||
|
||||
-h, --help
|
||||
Print help (see a summary with '-h')
|
||||
|
||||
```
|
||||
|
||||
The `render` command can be used to apply a shader preset to an image. The available runtimes will depend on the platform
|
||||
|
@ -93,6 +107,19 @@ Options:
|
|||
-p, --preset <PRESET>
|
||||
The path to the shader preset to load
|
||||
|
||||
-w, --wildcards <WILDCARDS>...
|
||||
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
|
||||
|
||||
--params <PARAMS>...
|
||||
Parameters to pass to the shader preset, comma separated with equals signs.
|
||||
|
||||
For example, crt_gamma=2.5,halation_weight=0.001
|
||||
|
||||
--passes-enabled <PASSES_ENABLED>
|
||||
Set the number of passes enabled for the preset
|
||||
|
||||
-i, --image <IMAGE>
|
||||
The path to the input image
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ use librashader::reflect::cross::{GlslVersion, HlslShaderModel, MslVersion, Spir
|
|||
use librashader::reflect::naga::{Naga, NagaLoweringOptions};
|
||||
use librashader::reflect::semantics::ShaderSemantics;
|
||||
use librashader::reflect::{CompileShader, FromCompilation, ReflectShader, SpirvCompilation};
|
||||
use librashader::{FastHashMap, ShortString};
|
||||
use librashader_runtime::parameters::RuntimeParameters;
|
||||
use librashader_test::render::RenderTest;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
|
@ -28,6 +30,21 @@ enum Commands {
|
|||
/// 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>>,
|
||||
/// 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,
|
||||
|
@ -49,6 +66,20 @@ enum Commands {
|
|||
/// 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>>,
|
||||
/// 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,
|
||||
|
@ -241,12 +272,22 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||
Commands::Render {
|
||||
frame,
|
||||
preset,
|
||||
wildcards,
|
||||
params,
|
||||
passes_enabled,
|
||||
image,
|
||||
out,
|
||||
runtime,
|
||||
} => {
|
||||
let test: &mut dyn RenderTest = get_runtime!(runtime, image);
|
||||
let image = test.render(preset.as_path(), frame)?;
|
||||
let preset = get_shader_preset(preset, wildcards)?;
|
||||
let params = parse_params(params)?;
|
||||
|
||||
let image = test.render_with_preset_and_params(
|
||||
preset,
|
||||
frame,
|
||||
Some(&|rp| set_params(rp, ¶ms, passes_enabled)),
|
||||
)?;
|
||||
|
||||
if out.as_path() == Path::new("-") {
|
||||
let out = std::io::stdout();
|
||||
|
@ -258,6 +299,9 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||
Commands::Compare {
|
||||
frame,
|
||||
preset,
|
||||
wildcards,
|
||||
params,
|
||||
passes_enabled,
|
||||
image,
|
||||
left,
|
||||
right,
|
||||
|
@ -265,9 +309,22 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||
} => {
|
||||
let left: &mut dyn RenderTest = get_runtime!(left, image);
|
||||
let right: &mut dyn RenderTest = get_runtime!(right, image);
|
||||
let params = parse_params(params)?;
|
||||
|
||||
let left_preset = get_shader_preset(preset.clone(), wildcards.clone())?;
|
||||
let left_image = left.render_with_preset_and_params(
|
||||
left_preset,
|
||||
frame,
|
||||
Some(&|rp| set_params(rp, ¶ms, passes_enabled)),
|
||||
)?;
|
||||
|
||||
let right_preset = get_shader_preset(preset.clone(), wildcards.clone())?;
|
||||
let right_image = right.render_with_preset_and_params(
|
||||
right_preset,
|
||||
frame,
|
||||
Some(&|rp| set_params(rp, ¶ms, passes_enabled)),
|
||||
)?;
|
||||
|
||||
let left_image = left.render(preset.as_path(), frame)?;
|
||||
let right_image = right.render(preset.as_path(), frame)?;
|
||||
let similarity = image_compare::rgba_hybrid_compare(&left_image, &right_image)?;
|
||||
print!("{}", similarity.score);
|
||||
|
||||
|
@ -312,7 +369,8 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||
librashader::reflect::targets::GLSL::from_compilation(compilation)?;
|
||||
compilation.validate()?;
|
||||
|
||||
let version = version.map(|s| parse_glsl_version(&s))
|
||||
let version = version
|
||||
.map(|s| parse_glsl_version(&s))
|
||||
.unwrap_or(Ok(GlslVersion::Glsl330))?;
|
||||
|
||||
let output = compilation.compile(version)?;
|
||||
|
@ -326,7 +384,8 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||
librashader::reflect::targets::HLSL::from_compilation(compilation)?;
|
||||
compilation.validate()?;
|
||||
|
||||
let shader_model = version.map(|s| parse_hlsl_version(&s))
|
||||
let shader_model = version
|
||||
.map(|s| parse_hlsl_version(&s))
|
||||
.unwrap_or(Ok(HlslShaderModel::ShaderModel5_0))?;
|
||||
|
||||
let output = compilation.compile(Some(shader_model))?;
|
||||
|
@ -356,7 +415,8 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||
>>::from_compilation(compilation)?;
|
||||
compilation.validate()?;
|
||||
|
||||
let version = version.map(|s| parse_msl_version(&s))
|
||||
let version = version
|
||||
.map(|s| parse_msl_version(&s))
|
||||
.unwrap_or(Ok(MslVersion::new(1, 2, 0)))?;
|
||||
|
||||
let output = compilation.compile(Some(version))?;
|
||||
|
@ -459,6 +519,49 @@ fn get_shader_preset(
|
|||
Ok(preset)
|
||||
}
|
||||
|
||||
fn parse_params(
|
||||
assignments: Option<Vec<String>>,
|
||||
) -> anyhow::Result<Option<FastHashMap<ShortString, f32>>> {
|
||||
let Some(assignments) = assignments else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let mut map = FastHashMap::default();
|
||||
for string in assignments {
|
||||
let Some((left, right)) = string.split_once("=") else {
|
||||
return Err(anyhow!("Encountered invalid parameter string {string}"));
|
||||
};
|
||||
|
||||
let value = right
|
||||
.parse::<f32>()
|
||||
.map_err(|_| anyhow!("Encountered invalid parameter value: {right}"))?;
|
||||
|
||||
map.insert(ShortString::from(left), value);
|
||||
}
|
||||
|
||||
Ok(Some(map))
|
||||
}
|
||||
|
||||
fn set_params(
|
||||
params: &RuntimeParameters,
|
||||
assignments: &Option<FastHashMap<ShortString, f32>>,
|
||||
passes_enabled: Option<usize>,
|
||||
) {
|
||||
if let Some(passes_enabled) = passes_enabled {
|
||||
params.set_passes_enabled(passes_enabled)
|
||||
};
|
||||
|
||||
let Some(assignments) = assignments else {
|
||||
return;
|
||||
};
|
||||
|
||||
params.update_parameters(|params| {
|
||||
for (key, param) in assignments {
|
||||
params.insert(key.clone(), *param);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn spirv_to_dis(spirv: Vec<u32>) -> anyhow::Result<String> {
|
||||
let binary = spq_spvasm::SpirvBinary::from(spirv);
|
||||
spq_spvasm::Disassembler::new()
|
||||
|
@ -473,7 +576,7 @@ fn spirv_to_dis(spirv: Vec<u32>) -> anyhow::Result<String> {
|
|||
fn parse_glsl_version(version_str: &str) -> anyhow::Result<GlslVersion> {
|
||||
if version_str.contains("es") {
|
||||
let Some(version) = version_str.strip_suffix("es").map(|s| s.trim()) else {
|
||||
return Err(anyhow!("Unknown GLSL version"))
|
||||
return Err(anyhow!("Unknown GLSL version"));
|
||||
};
|
||||
|
||||
Ok(match version {
|
||||
|
@ -516,7 +619,9 @@ fn version_to_usize(version_str: &str) -> anyhow::Result<usize> {
|
|||
version_str
|
||||
};
|
||||
|
||||
let version = version.parse::<usize>().map_err(|_| anyhow!("Invalid version string"))?;
|
||||
let version = version
|
||||
.parse::<usize>()
|
||||
.map_err(|_| anyhow!("Invalid version string"))?;
|
||||
Ok(version)
|
||||
}
|
||||
|
||||
|
@ -562,4 +667,4 @@ fn parse_msl_version(version_str: &str) -> anyhow::Result<MslVersion> {
|
|||
}
|
||||
_ => return Err(anyhow!("Unknown MSL version")),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::render::RenderTest;
|
|||
use anyhow::anyhow;
|
||||
use image::RgbaImage;
|
||||
use librashader::runtime::d3d11::*;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use librashader::runtime::{Size, Viewport};
|
||||
use std::path::Path;
|
||||
|
||||
|
@ -13,18 +14,28 @@ impl RenderTest for Direct3D11 {
|
|||
Direct3D11::new(path)
|
||||
}
|
||||
|
||||
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
let (renderbuffer, rtv) = self.create_renderbuffer(self.image_bytes.size)?;
|
||||
|
||||
unsafe {
|
||||
let mut filter_chain = FilterChain::load_from_path(
|
||||
path,
|
||||
let mut filter_chain = FilterChain::load_from_preset(
|
||||
preset,
|
||||
&self.device,
|
||||
Some(&FilterChainOptions {
|
||||
force_no_mipmaps: false,
|
||||
disable_cache: false,
|
||||
}),
|
||||
)?;
|
||||
|
||||
if let Some(setter) = param_setter {
|
||||
setter(filter_chain.parameters());
|
||||
}
|
||||
|
||||
filter_chain.frame(
|
||||
None,
|
||||
&self.image_srv,
|
||||
|
@ -78,6 +89,7 @@ impl RenderTest for Direct3D11 {
|
|||
}
|
||||
}
|
||||
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader_runtime::image::{Image, UVDirection};
|
||||
use windows::{
|
||||
Win32::Foundation::*, Win32::Graphics::Direct3D::*, Win32::Graphics::Direct3D11::*,
|
||||
|
|
|
@ -6,10 +6,12 @@ use crate::render::RenderTest;
|
|||
use anyhow::anyhow;
|
||||
use d3d12_descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot};
|
||||
use image::RgbaImage;
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader::runtime::d3d12::{
|
||||
D3D12InputImage, D3D12OutputView, FilterChain, FilterChainOptions,
|
||||
};
|
||||
use librashader::runtime::Viewport;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use librashader_runtime::image::{Image, PixelFormat, UVDirection, BGRA8};
|
||||
use std::path::Path;
|
||||
use windows::core::Interface;
|
||||
|
@ -58,7 +60,12 @@ impl RenderTest for Direct3D12 {
|
|||
Direct3D12::new(path)
|
||||
}
|
||||
|
||||
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
unsafe {
|
||||
let descriptor = self.rtv_heap.allocate_descriptor()?;
|
||||
|
||||
|
@ -72,8 +79,8 @@ impl RenderTest for Direct3D12 {
|
|||
let fence_event = CreateEventA(None, false, false, None)?;
|
||||
let fence: ID3D12Fence = self.device.CreateFence(0, D3D12_FENCE_FLAG_NONE)?;
|
||||
|
||||
let mut filter_chain = FilterChain::load_from_path(
|
||||
path,
|
||||
let mut filter_chain = FilterChain::load_from_preset(
|
||||
preset,
|
||||
&self.device,
|
||||
Some(&FilterChainOptions {
|
||||
force_hlsl_pipeline: false,
|
||||
|
@ -82,6 +89,10 @@ impl RenderTest for Direct3D12 {
|
|||
}),
|
||||
)?;
|
||||
|
||||
if let Some(setter) = param_setter {
|
||||
setter(filter_chain.parameters());
|
||||
}
|
||||
|
||||
let mut output_texture = None;
|
||||
let desc = D3D12_RESOURCE_DESC {
|
||||
Dimension: D3D12_RESOURCE_DIMENSION_TEXTURE2D,
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use crate::render::RenderTest;
|
||||
use anyhow::anyhow;
|
||||
use image::RgbaImage;
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader::runtime::d3d9::{FilterChain, FilterChainOptions};
|
||||
use librashader::runtime::Viewport;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use librashader_runtime::image::{Image, PixelFormat, UVDirection, BGRA8};
|
||||
use std::path::Path;
|
||||
use windows::Win32::Foundation::{HWND, TRUE};
|
||||
|
@ -29,10 +31,15 @@ impl RenderTest for Direct3D9 {
|
|||
Direct3D9::new(path)
|
||||
}
|
||||
|
||||
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
unsafe {
|
||||
let mut filter_chain = FilterChain::load_from_path(
|
||||
path,
|
||||
let mut filter_chain = FilterChain::load_from_preset(
|
||||
preset,
|
||||
&self.device,
|
||||
Some(&FilterChainOptions {
|
||||
force_no_mipmaps: false,
|
||||
|
@ -40,6 +47,10 @@ impl RenderTest for Direct3D9 {
|
|||
}),
|
||||
)?;
|
||||
|
||||
if let Some(setter) = param_setter {
|
||||
setter(filter_chain.parameters());
|
||||
}
|
||||
|
||||
let mut render_texture = None;
|
||||
|
||||
self.device.CreateTexture(
|
||||
|
|
|
@ -5,8 +5,10 @@ use crate::render::RenderTest;
|
|||
use anyhow::anyhow;
|
||||
use glow::{HasContext, PixelPackData, PixelUnpackData};
|
||||
use image::RgbaImage;
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader::runtime::gl::{FilterChain, FilterChainOptions, GLImage};
|
||||
use librashader::runtime::Viewport;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use librashader_runtime::image::{Image, UVDirection, RGBA8};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
@ -28,10 +30,15 @@ impl RenderTest for OpenGl3 {
|
|||
OpenGl3::new(path)
|
||||
}
|
||||
|
||||
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
let mut filter_chain = unsafe {
|
||||
FilterChain::load_from_path(
|
||||
path,
|
||||
FilterChain::load_from_preset(
|
||||
preset,
|
||||
Arc::clone(&self.0.context.gl),
|
||||
Some(&FilterChainOptions {
|
||||
glsl_version: 330,
|
||||
|
@ -42,6 +49,10 @@ impl RenderTest for OpenGl3 {
|
|||
)
|
||||
}?;
|
||||
|
||||
if let Some(setter) = param_setter {
|
||||
setter(filter_chain.parameters());
|
||||
}
|
||||
|
||||
Ok(self.0.render(&mut filter_chain, frame_count)?)
|
||||
}
|
||||
}
|
||||
|
@ -54,10 +65,15 @@ impl RenderTest for OpenGl4 {
|
|||
OpenGl4::new(path)
|
||||
}
|
||||
|
||||
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
let mut filter_chain = unsafe {
|
||||
FilterChain::load_from_path(
|
||||
path,
|
||||
FilterChain::load_from_preset(
|
||||
preset,
|
||||
Arc::clone(&self.0.context.gl),
|
||||
Some(&FilterChainOptions {
|
||||
glsl_version: 460,
|
||||
|
@ -68,6 +84,10 @@ impl RenderTest for OpenGl4 {
|
|||
)
|
||||
}?;
|
||||
|
||||
if let Some(setter) = param_setter {
|
||||
setter(filter_chain.parameters());
|
||||
}
|
||||
|
||||
Ok(self.0.render(&mut filter_chain, frame_count)?)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ pub mod wgpu;
|
|||
#[cfg(all(target_vendor = "apple", feature = "metal"))]
|
||||
pub mod mtl;
|
||||
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader_runtime::parameters::RuntimeParameters;
|
||||
use std::path::Path;
|
||||
|
||||
/// Test harness to set up a device, render a triangle, and apply a shader
|
||||
|
@ -36,7 +38,41 @@ pub trait RenderTest {
|
|||
/// For testing purposes, it is often that a single image will be reused with multiple
|
||||
/// shader presets, so the actual image that a shader will be applied to
|
||||
/// will often be part of the test harness object.
|
||||
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<image::RgbaImage>;
|
||||
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<image::RgbaImage> {
|
||||
let preset = ShaderPreset::try_parse(path)?;
|
||||
self.render_with_preset(preset, frame_count)
|
||||
}
|
||||
|
||||
/// Render a shader onto an image buffer, applying the provided shader.
|
||||
///
|
||||
/// The test should render in linear colour space for proper comparison against
|
||||
/// backends.
|
||||
///
|
||||
/// For testing purposes, it is often that a single image will be reused with multiple
|
||||
/// shader presets, so the actual image that a shader will be applied to
|
||||
/// will often be part of the test harness object.
|
||||
fn render_with_preset(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
self.render_with_preset_and_params(preset, frame_count, None)
|
||||
}
|
||||
|
||||
/// Render a shader onto an image buffer, applying the provided shader.
|
||||
///
|
||||
/// The test should render in linear colour space for proper comparison against
|
||||
/// backends.
|
||||
///
|
||||
/// For testing purposes, it is often that a single image will be reused with multiple
|
||||
/// shader presets, so the actual image that a shader will be applied to
|
||||
/// will often be part of the test harness object.
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
) -> anyhow::Result<image::RgbaImage>;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use crate::render::RenderTest;
|
||||
use anyhow::anyhow;
|
||||
use image::RgbaImage;
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader::runtime::mtl::{FilterChain, FilterChainOptions};
|
||||
use librashader::runtime::Viewport;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use librashader_runtime::image::{Image, PixelFormat, UVDirection, BGRA8, RGBA8};
|
||||
use objc2::ffi::NSUInteger;
|
||||
use objc2::rc::Retained;
|
||||
|
@ -29,7 +31,12 @@ impl RenderTest for Metal {
|
|||
Metal::new(path)
|
||||
}
|
||||
|
||||
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
let queue = self
|
||||
.device
|
||||
.newCommandQueue()
|
||||
|
@ -39,14 +46,18 @@ impl RenderTest for Metal {
|
|||
.commandBuffer()
|
||||
.ok_or_else(|| anyhow!("Unable to create command buffer"))?;
|
||||
|
||||
let mut filter_chain = FilterChain::load_from_path(
|
||||
path,
|
||||
let mut filter_chain = FilterChain::load_from_preset(
|
||||
preset,
|
||||
&queue,
|
||||
Some(&FilterChainOptions {
|
||||
force_no_mipmaps: false,
|
||||
}),
|
||||
)?;
|
||||
|
||||
if let Some(setter) = param_setter {
|
||||
setter(filter_chain.parameters());
|
||||
}
|
||||
|
||||
let render_texture = unsafe {
|
||||
let texture_descriptor =
|
||||
MTLTextureDescriptor::texture2DDescriptorWithPixelFormat_width_height_mipmapped(
|
||||
|
|
|
@ -5,8 +5,10 @@ use anyhow::anyhow;
|
|||
use ash::vk;
|
||||
use gpu_allocator::MemoryLocation;
|
||||
use image::RgbaImage;
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader::runtime::vk::{FilterChain, FilterChainOptions, VulkanImage};
|
||||
use librashader::runtime::Viewport;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use librashader_runtime::image::{Image, UVDirection, BGRA8};
|
||||
use std::path::Path;
|
||||
|
||||
|
@ -30,10 +32,15 @@ impl RenderTest for Vulkan {
|
|||
Vulkan::new(path)
|
||||
}
|
||||
|
||||
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
unsafe {
|
||||
let mut filter_chain = FilterChain::load_from_path(
|
||||
path,
|
||||
let mut filter_chain = FilterChain::load_from_preset(
|
||||
preset,
|
||||
&self.vk,
|
||||
Some(&FilterChainOptions {
|
||||
frames_in_flight: 3,
|
||||
|
@ -43,6 +50,10 @@ impl RenderTest for Vulkan {
|
|||
}),
|
||||
)?;
|
||||
|
||||
if let Some(setter) = param_setter {
|
||||
setter(filter_chain.parameters());
|
||||
}
|
||||
|
||||
let image_info = vk::ImageCreateInfo::default()
|
||||
.image_type(vk::ImageType::TYPE_2D)
|
||||
.format(vk::Format::B8G8R8A8_UNORM)
|
||||
|
|
|
@ -14,6 +14,8 @@ use wgpu_types::{
|
|||
ImageDataLayout, Maintain, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
|
||||
};
|
||||
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use parking_lot::Mutex;
|
||||
|
||||
pub struct Wgpu {
|
||||
|
@ -54,9 +56,14 @@ impl RenderTest for Wgpu {
|
|||
Wgpu::new(path)
|
||||
}
|
||||
|
||||
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||
let mut chain = FilterChain::load_from_path(
|
||||
path,
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
let mut chain = FilterChain::load_from_preset(
|
||||
preset,
|
||||
Arc::clone(&self.device),
|
||||
Arc::clone(&self.queue),
|
||||
Some(&FilterChainOptions {
|
||||
|
@ -65,7 +72,9 @@ impl RenderTest for Wgpu {
|
|||
adapter_info: None,
|
||||
}),
|
||||
)?;
|
||||
|
||||
if let Some(setter) = param_setter {
|
||||
setter(&chain.parameters());
|
||||
}
|
||||
let mut cmd = self
|
||||
.device
|
||||
.create_command_encoder(&CommandEncoderDescriptor { label: None });
|
||||
|
|
|
@ -42,6 +42,7 @@ impl RuntimeParameters {
|
|||
/// Set a runtime parameter.
|
||||
///
|
||||
/// This is a relatively slow operation as it will be synchronized across threads.
|
||||
/// If updating multiple parameters, see [`RuntimeParameters::update_parameters`].
|
||||
pub fn set_parameter_value(&self, name: &str, new_value: f32) -> Option<f32> {
|
||||
let mut updated_map = FastHashMap::clone(&self.parameters.load());
|
||||
|
||||
|
@ -57,6 +58,13 @@ impl RuntimeParameters {
|
|||
}
|
||||
}
|
||||
|
||||
/// Update multiple runtime parameters atomically through a function.
|
||||
pub fn update_parameters(&self, updater: impl FnOnce(&mut FastHashMap<ShortString, f32>)) {
|
||||
let mut updated_map = FastHashMap::clone(&self.parameters.load());
|
||||
updater(&mut updated_map);
|
||||
self.parameters.store(Arc::new(updated_map));
|
||||
}
|
||||
|
||||
/// Get a reference to the runtime parameters.
|
||||
pub fn parameters(&self) -> Arc<FastHashMap<ShortString, f32>> {
|
||||
self.parameters.load_full()
|
||||
|
|
Loading…
Reference in a new issue