cli(render): allow specifying output dimensions
This commit is contained in:
parent
4abd48eb24
commit
95a489ee12
11
CLI.md
11
CLI.md
|
@ -9,6 +9,7 @@ Commands:
|
|||
render Render a shader preset against an image
|
||||
compare Compare two runtimes and get a similarity score between the two runtimes rendering the same frame
|
||||
parse Parse a preset and get a JSON representation of the data
|
||||
pack Create a serialized preset pack from a shader preset
|
||||
preprocess Get the raw GLSL output of a preprocessed shader
|
||||
transpile Transpile a shader in a given preset to the given format
|
||||
reflect Reflect the shader relative to a preset, giving information about semantics used in a slang shader
|
||||
|
@ -53,6 +54,11 @@ Options:
|
|||
|
||||
[default: 0]
|
||||
|
||||
-d, --dimensions <DIMENSIONS>
|
||||
The dimensions of the image.
|
||||
|
||||
This is given in either explicit dimensions `WIDTHxHEIGHT`, or a percentage of the input image in `SCALE%`.
|
||||
|
||||
--params <PARAMS>...
|
||||
Parameters to pass to the shader preset, comma separated with equals signs.
|
||||
|
||||
|
@ -137,6 +143,11 @@ Options:
|
|||
|
||||
[default: 0]
|
||||
|
||||
-d, --dimensions <DIMENSIONS>
|
||||
The dimensions of the image.
|
||||
|
||||
This is given in either explicit dimensions `WIDTHxHEIGHT`, or a percentage of the input image in `SCALE%`.
|
||||
|
||||
--params <PARAMS>...
|
||||
Parameters to pass to the shader preset, comma separated with equals signs.
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ Commands:
|
|||
render Render a shader preset against an image
|
||||
compare Compare two runtimes and get a similarity score between the two runtimes rendering the same frame
|
||||
parse Parse a preset and get a JSON representation of the data
|
||||
pack Create a serialized preset pack from a shader preset
|
||||
preprocess Get the raw GLSL output of a preprocessed shader
|
||||
transpile Transpile a shader in a given preset to the given format
|
||||
reflect Reflect the shader relative to a preset, giving information about semantics used in a slang shader
|
||||
|
|
|
@ -49,7 +49,7 @@ pub enum LIBRA_PRESET_CTX_RUNTIME {
|
|||
/// Metal
|
||||
Metal,
|
||||
/// Direct3D 9
|
||||
D3D9_HLSL
|
||||
D3D9_HLSL,
|
||||
}
|
||||
|
||||
impl From<LIBRA_PRESET_CTX_RUNTIME> for VideoDriver {
|
||||
|
@ -61,7 +61,7 @@ impl From<LIBRA_PRESET_CTX_RUNTIME> for VideoDriver {
|
|||
LIBRA_PRESET_CTX_RUNTIME::D3D11 => VideoDriver::Direct3D11,
|
||||
LIBRA_PRESET_CTX_RUNTIME::D3D12 => VideoDriver::Direct3D12,
|
||||
LIBRA_PRESET_CTX_RUNTIME::Metal => VideoDriver::Metal,
|
||||
LIBRA_PRESET_CTX_RUNTIME::D3D9_HLSL => VideoDriver::Direct3D9Hlsl
|
||||
LIBRA_PRESET_CTX_RUNTIME::D3D9_HLSL => VideoDriver::Direct3D9Hlsl,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ 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::runtime::Size;
|
||||
use librashader::{FastHashMap, ShortString};
|
||||
use librashader_runtime::parameters::RuntimeParameters;
|
||||
use librashader_test::render::{CommonFrameOptions, RenderTest};
|
||||
|
@ -43,6 +44,12 @@ struct RenderArgs {
|
|||
/// to ensure feedback and history.
|
||||
#[arg(short, long, default_value_t = 0)]
|
||||
frame: usize,
|
||||
/// The dimensions of the image.
|
||||
///
|
||||
/// This is given in either explicit dimensions `WIDTHxHEIGHT`, or a
|
||||
/// percentage of the input image in `SCALE%`.
|
||||
#[arg(short, long)]
|
||||
dimensions: Option<String>,
|
||||
/// Parameters to pass to the shader preset, comma separated with equals signs.
|
||||
///
|
||||
/// For example, crt_gamma=2.5,halation_weight=0.001
|
||||
|
@ -313,6 +320,7 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||
let PresetArgs { preset, wildcards } = preset;
|
||||
let RenderArgs {
|
||||
frame,
|
||||
dimensions,
|
||||
params,
|
||||
passes_enabled,
|
||||
image,
|
||||
|
@ -320,13 +328,14 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||
} = render;
|
||||
|
||||
let test: &mut dyn RenderTest = get_runtime!(runtime, image);
|
||||
|
||||
let dimensions = parse_dimension(dimensions, test.image_size())?;
|
||||
let preset = get_shader_preset(preset, wildcards)?;
|
||||
let params = parse_params(params)?;
|
||||
|
||||
let image = test.render_with_preset_and_params(
|
||||
preset,
|
||||
frame,
|
||||
Some(dimensions),
|
||||
Some(&|rp| set_params(rp, ¶ms, passes_enabled)),
|
||||
options.map(CommonFrameOptions::from),
|
||||
)?;
|
||||
|
@ -348,6 +357,7 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||
let PresetArgs { preset, wildcards } = preset;
|
||||
let RenderArgs {
|
||||
frame,
|
||||
dimensions,
|
||||
params,
|
||||
passes_enabled,
|
||||
image,
|
||||
|
@ -357,12 +367,14 @@ 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 dimensions = parse_dimension(dimensions, left.image_size())?;
|
||||
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(dimensions),
|
||||
Some(&|rp| set_params(rp, ¶ms, passes_enabled)),
|
||||
None,
|
||||
)?;
|
||||
|
@ -371,6 +383,7 @@ pub fn main() -> Result<(), anyhow::Error> {
|
|||
let right_image = right.render_with_preset_and_params(
|
||||
right_preset,
|
||||
frame,
|
||||
Some(dimensions),
|
||||
Some(&|rp| set_params(rp, ¶ms, passes_enabled)),
|
||||
options.map(CommonFrameOptions::from),
|
||||
)?;
|
||||
|
@ -742,3 +755,47 @@ fn parse_msl_version(version_str: &str) -> anyhow::Result<MslVersion> {
|
|||
_ => return Err(anyhow!("Unknown MSL version")),
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_dimension(dimstr: Option<String>, image_dim: Size<u32>) -> anyhow::Result<Size<u32>> {
|
||||
let Some(dimstr) = dimstr else {
|
||||
return Ok(image_dim);
|
||||
};
|
||||
|
||||
if dimstr.contains("x") {
|
||||
if let Some((Ok(width), Ok(height))) = dimstr
|
||||
.split_once("x")
|
||||
.map(|(width, height)| (width.parse::<u32>(), height.parse::<u32>()))
|
||||
{
|
||||
if width < 1 || height < 1 {
|
||||
return Err(anyhow!("Dimensions must be larger than 1x1"));
|
||||
}
|
||||
|
||||
if width > 16384 || height > 16384 {
|
||||
return Err(anyhow!("Dimensions must not be larger than 16384x16384"));
|
||||
}
|
||||
return Ok(Size::new(width, height));
|
||||
}
|
||||
}
|
||||
|
||||
if dimstr.ends_with("%") && dimstr.len() > 1 {
|
||||
if let Ok(percent) = dimstr.trim_end_matches("%").parse::<u32>() {
|
||||
let percent = percent as f32 / 100f32;
|
||||
let width = (image_dim.width as f32 * percent) as u32;
|
||||
let height = (image_dim.height as f32 * percent) as u32;
|
||||
|
||||
if width < 1 || height < 1 {
|
||||
return Err(anyhow!("Dimensions must be larger than 1x1"));
|
||||
}
|
||||
|
||||
if width > 16384 || height > 16384 {
|
||||
return Err(anyhow!("Dimensions must not be larger than 16384x16384"));
|
||||
}
|
||||
|
||||
return Ok(Size { width, height });
|
||||
}
|
||||
}
|
||||
|
||||
Err(anyhow!(
|
||||
"Invalid dimension syntax, must either in form WIDTHxHEIGHT or SCALE%"
|
||||
))
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ use image::RgbaImage;
|
|||
use librashader::runtime::d3d11::*;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use librashader::runtime::{Size, Viewport};
|
||||
use std::io::{Cursor, Write};
|
||||
use std::ops::DerefMut;
|
||||
use std::path::Path;
|
||||
|
||||
impl RenderTest for Direct3D11 {
|
||||
|
@ -14,14 +16,20 @@ impl RenderTest for Direct3D11 {
|
|||
Direct3D11::new(path)
|
||||
}
|
||||
|
||||
fn image_size(&self) -> Size<u32> {
|
||||
self.image_bytes.size
|
||||
}
|
||||
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
output_size: Option<Size<u32>>,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
frame_options: Option<CommonFrameOptions>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
let (renderbuffer, rtv) = self.create_renderbuffer(self.image_bytes.size)?;
|
||||
let output_size = output_size.unwrap_or(self.image_bytes.size);
|
||||
let (renderbuffer, rtv) = self.create_renderbuffer(output_size)?;
|
||||
|
||||
unsafe {
|
||||
let mut filter_chain = FilterChain::load_from_preset(
|
||||
|
@ -50,10 +58,10 @@ impl RenderTest for Direct3D11 {
|
|||
}
|
||||
|
||||
let mut renderbuffer_desc = Default::default();
|
||||
self.immediate_context.Flush();
|
||||
renderbuffer.GetDesc(&mut renderbuffer_desc);
|
||||
|
||||
self.immediate_context.Flush();
|
||||
|
||||
eprintln!("{:?}", renderbuffer_desc);
|
||||
let mut staging = None;
|
||||
self.device.CreateTexture2D(
|
||||
&D3D11_TEXTURE2D_DESC {
|
||||
|
@ -72,6 +80,8 @@ impl RenderTest for Direct3D11 {
|
|||
|
||||
self.immediate_context.CopyResource(&staging, &renderbuffer);
|
||||
|
||||
let mut pixels: Vec<u8> = Vec::new();
|
||||
|
||||
let mut map_info = Default::default();
|
||||
self.immediate_context
|
||||
.Map(&staging, 0, D3D11_MAP_READ, 0, Some(&mut map_info))?;
|
||||
|
@ -80,13 +90,18 @@ impl RenderTest for Direct3D11 {
|
|||
map_info.pData as *const u8,
|
||||
(renderbuffer_desc.Height * map_info.RowPitch) as usize,
|
||||
);
|
||||
pixels.resize(
|
||||
(renderbuffer_desc.Height * renderbuffer_desc.Width * 4) as usize,
|
||||
0,
|
||||
);
|
||||
|
||||
let image = RgbaImage::from_raw(
|
||||
renderbuffer_desc.Width,
|
||||
renderbuffer_desc.Height,
|
||||
Vec::from(slice),
|
||||
)
|
||||
.ok_or(anyhow!("Unable to create image from data"))?;
|
||||
let mut cursor = Cursor::new(pixels.deref_mut());
|
||||
for chunk in slice.chunks(map_info.RowPitch as usize) {
|
||||
cursor.write_all(&chunk[..(renderbuffer_desc.Width * 4) as usize])?
|
||||
}
|
||||
|
||||
let image = RgbaImage::from_raw(output_size.width, output_size.height, pixels)
|
||||
.ok_or(anyhow!("Unable to create image from data"))?;
|
||||
self.immediate_context.Unmap(&staging, 0);
|
||||
|
||||
Ok(image)
|
||||
|
|
|
@ -8,8 +8,8 @@ use d3d12_descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot};
|
|||
use image::RgbaImage;
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader::runtime::d3d12::{D3D12OutputView, FilterChain, FilterChainOptions, FrameOptions};
|
||||
use librashader::runtime::Viewport;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use librashader::runtime::{Size, Viewport};
|
||||
use librashader_runtime::image::{Image, PixelFormat, UVDirection, BGRA8};
|
||||
use std::path::Path;
|
||||
use windows::core::Interface;
|
||||
|
@ -58,10 +58,14 @@ impl RenderTest for Direct3D12 {
|
|||
Direct3D12::new(path)
|
||||
}
|
||||
|
||||
fn image_size(&self) -> Size<u32> {
|
||||
self.image.size
|
||||
}
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
output_size: Option<Size<u32>>,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
frame_options: Option<CommonFrameOptions>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
|
@ -92,12 +96,13 @@ impl RenderTest for Direct3D12 {
|
|||
setter(filter_chain.parameters());
|
||||
}
|
||||
|
||||
let output_size = output_size.unwrap_or(self.image.size);
|
||||
let mut output_texture = None;
|
||||
let desc = D3D12_RESOURCE_DESC {
|
||||
Dimension: D3D12_RESOURCE_DIMENSION_TEXTURE2D,
|
||||
Alignment: 0,
|
||||
Width: self.image.size.width as u64,
|
||||
Height: self.image.size.height,
|
||||
Width: output_size.width as u64,
|
||||
Height: output_size.height,
|
||||
DepthOrArraySize: 1,
|
||||
MipLevels: 1,
|
||||
Format: DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
|
@ -135,7 +140,7 @@ impl RenderTest for Direct3D12 {
|
|||
let viewport = Viewport::new_render_target_sized_origin(
|
||||
D3D12OutputView::new_from_raw(
|
||||
*descriptor.as_ref(),
|
||||
self.image.size,
|
||||
output_size,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
),
|
||||
None,
|
||||
|
@ -165,11 +170,11 @@ impl RenderTest for Direct3D12 {
|
|||
CloseHandle(fence_event)?;
|
||||
};
|
||||
|
||||
let mut buffer = vec![0u8; self.image.bytes.len()];
|
||||
let mut buffer = vec![0u8; (output_size.height * output_size.width) as usize * 4];
|
||||
|
||||
output_texture.ReadFromSubresource(
|
||||
buffer.as_mut_ptr().cast(),
|
||||
4 * self.image.size.width,
|
||||
4 * output_size.width,
|
||||
0,
|
||||
0,
|
||||
None,
|
||||
|
@ -177,12 +182,9 @@ impl RenderTest for Direct3D12 {
|
|||
|
||||
BGRA8::convert(&mut buffer);
|
||||
|
||||
let image = RgbaImage::from_raw(
|
||||
self.image.size.width,
|
||||
self.image.size.height,
|
||||
Vec::from(buffer),
|
||||
)
|
||||
.ok_or(anyhow!("Unable to create image from data"))?;
|
||||
let image =
|
||||
RgbaImage::from_raw(output_size.width, output_size.height, Vec::from(buffer))
|
||||
.ok_or(anyhow!("Unable to create image from data"))?;
|
||||
|
||||
Ok(image)
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ use anyhow::anyhow;
|
|||
use image::RgbaImage;
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader::runtime::d3d9::{FilterChain, FilterChainOptions, FrameOptions};
|
||||
use librashader::runtime::Viewport;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use librashader::runtime::{Size, Viewport};
|
||||
use librashader_runtime::image::{Image, PixelFormat, UVDirection, BGRA8};
|
||||
use std::path::Path;
|
||||
use windows::Win32::Foundation::{HWND, TRUE};
|
||||
|
@ -31,10 +31,15 @@ impl RenderTest for Direct3D9 {
|
|||
Direct3D9::new(path)
|
||||
}
|
||||
|
||||
fn image_size(&self) -> Size<u32> {
|
||||
self.image.size
|
||||
}
|
||||
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
output_size: Option<Size<u32>>,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
frame_options: Option<CommonFrameOptions>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
|
@ -54,9 +59,10 @@ impl RenderTest for Direct3D9 {
|
|||
|
||||
let mut render_texture = None;
|
||||
|
||||
let output_size = output_size.unwrap_or(self.image.size);
|
||||
self.device.CreateTexture(
|
||||
self.image.size.width,
|
||||
self.image.size.height,
|
||||
output_size.width,
|
||||
output_size.height,
|
||||
1,
|
||||
D3DUSAGE_RENDERTARGET as u32,
|
||||
D3DFMT_A8R8G8B8,
|
||||
|
@ -71,8 +77,8 @@ impl RenderTest for Direct3D9 {
|
|||
let mut copy_texture = None;
|
||||
|
||||
self.device.CreateOffscreenPlainSurface(
|
||||
self.image.size.width,
|
||||
self.image.size.height,
|
||||
output_size.width,
|
||||
output_size.height,
|
||||
D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
&mut copy_texture,
|
||||
|
@ -112,7 +118,7 @@ impl RenderTest for Direct3D9 {
|
|||
|
||||
BGRA8::convert(&mut buffer);
|
||||
|
||||
let image = RgbaImage::from_raw(self.image.size.width, self.image.size.height, buffer)
|
||||
let image = RgbaImage::from_raw(output_size.width, output_size.height, buffer)
|
||||
.ok_or(anyhow!("Unable to create image from data"))?;
|
||||
|
||||
Ok(image)
|
||||
|
|
|
@ -7,8 +7,8 @@ use glow::{HasContext, PixelPackData, PixelUnpackData};
|
|||
use image::RgbaImage;
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader::runtime::gl::{FilterChain, FilterChainOptions, FrameOptions, GLImage};
|
||||
use librashader::runtime::Viewport;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use librashader::runtime::{Size, Viewport};
|
||||
use librashader_runtime::image::{Image, UVDirection, RGBA8};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
@ -30,10 +30,15 @@ impl RenderTest for OpenGl3 {
|
|||
OpenGl3::new(path)
|
||||
}
|
||||
|
||||
fn image_size(&self) -> Size<u32> {
|
||||
self.0.image_bytes.size
|
||||
}
|
||||
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
output_size: Option<Size<u32>>,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
frame_options: Option<CommonFrameOptions>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
|
@ -57,6 +62,7 @@ impl RenderTest for OpenGl3 {
|
|||
Ok(self.0.render(
|
||||
&mut filter_chain,
|
||||
frame_count,
|
||||
output_size,
|
||||
frame_options
|
||||
.map(|options| FrameOptions {
|
||||
clear_history: options.clear_history,
|
||||
|
@ -78,10 +84,15 @@ impl RenderTest for OpenGl4 {
|
|||
OpenGl4::new(path)
|
||||
}
|
||||
|
||||
fn image_size(&self) -> Size<u32> {
|
||||
self.0.image_bytes.size
|
||||
}
|
||||
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
output_size: Option<Size<u32>>,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
frame_options: Option<CommonFrameOptions>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
|
@ -105,6 +116,7 @@ impl RenderTest for OpenGl4 {
|
|||
Ok(self.0.render(
|
||||
&mut filter_chain,
|
||||
frame_count,
|
||||
output_size,
|
||||
frame_options
|
||||
.map(|options| FrameOptions {
|
||||
clear_history: options.clear_history,
|
||||
|
@ -189,8 +201,11 @@ impl OpenGl {
|
|||
&self,
|
||||
chain: &mut FilterChain,
|
||||
frame_count: usize,
|
||||
output_size: Option<Size<u32>>,
|
||||
options: Option<&FrameOptions>,
|
||||
) -> Result<RgbaImage, anyhow::Error> {
|
||||
let output_size = output_size.unwrap_or(self.image_bytes.size);
|
||||
|
||||
let render_texture = unsafe {
|
||||
let tex = self
|
||||
.context
|
||||
|
@ -202,8 +217,8 @@ impl OpenGl {
|
|||
glow::TEXTURE_2D,
|
||||
1,
|
||||
glow::RGBA8,
|
||||
self.image_bytes.size.width as i32,
|
||||
self.image_bytes.size.height as i32,
|
||||
output_size.width as i32,
|
||||
output_size.height as i32,
|
||||
);
|
||||
self.context.gl.bind_texture(glow::TEXTURE_2D, None);
|
||||
tex
|
||||
|
@ -212,7 +227,7 @@ impl OpenGl {
|
|||
let output = GLImage {
|
||||
handle: Some(render_texture),
|
||||
format: glow::RGBA8,
|
||||
size: self.image_bytes.size,
|
||||
size: output_size,
|
||||
};
|
||||
|
||||
let viewport = Viewport::new_render_target_sized_origin(&output, None)?;
|
||||
|
@ -222,8 +237,7 @@ impl OpenGl {
|
|||
}
|
||||
}
|
||||
|
||||
// should be the same size as the input image
|
||||
let mut data = vec![0u8; self.image_bytes.bytes.len()];
|
||||
let mut data = vec![0u8; output_size.width as usize * output_size.height as usize * 4];
|
||||
|
||||
unsafe {
|
||||
self.context
|
||||
|
@ -237,11 +251,9 @@ impl OpenGl {
|
|||
PixelPackData::Slice(&mut data),
|
||||
)
|
||||
}
|
||||
Ok(RgbaImage::from_raw(
|
||||
self.image_bytes.size.width,
|
||||
self.image_bytes.size.height,
|
||||
data,
|
||||
Ok(
|
||||
RgbaImage::from_raw(output_size.width, output_size.height, data)
|
||||
.ok_or(anyhow!("failed to create image from slice"))?,
|
||||
)
|
||||
.ok_or(anyhow!("failed to create image from slice"))?)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ pub mod wgpu;
|
|||
pub mod mtl;
|
||||
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader::runtime::Size;
|
||||
use librashader_runtime::impl_default_frame_options;
|
||||
use librashader_runtime::parameters::RuntimeParameters;
|
||||
use std::path::Path;
|
||||
|
@ -31,6 +32,9 @@ pub trait RenderTest {
|
|||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Get the size of the image loaded.
|
||||
fn image_size(&self) -> Size<u32>;
|
||||
|
||||
/// Render a shader onto an image buffer, applying the provided shader.
|
||||
///
|
||||
/// The test should render in linear colour space for proper comparison against
|
||||
|
@ -39,9 +43,14 @@ 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,
|
||||
output_size: Option<Size<u32>>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
let preset = ShaderPreset::try_parse(path)?;
|
||||
self.render_with_preset(preset, frame_count)
|
||||
self.render_with_preset(preset, frame_count, output_size)
|
||||
}
|
||||
|
||||
/// Render a shader onto an image buffer, applying the provided shader.
|
||||
|
@ -56,8 +65,9 @@ pub trait RenderTest {
|
|||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
output_size: Option<Size<u32>>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
self.render_with_preset_and_params(preset, frame_count, None, None)
|
||||
self.render_with_preset_and_params(preset, frame_count, output_size, None, None)
|
||||
}
|
||||
|
||||
/// Render a shader onto an image buffer, applying the provided shader.
|
||||
|
@ -72,6 +82,7 @@ pub trait RenderTest {
|
|||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
output_size: Option<Size<u32>>,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
frame_options: Option<CommonFrameOptions>,
|
||||
) -> anyhow::Result<image::RgbaImage>;
|
||||
|
|
|
@ -3,8 +3,8 @@ use anyhow::anyhow;
|
|||
use image::RgbaImage;
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader::runtime::mtl::{FilterChain, FilterChainOptions, FrameOptions};
|
||||
use librashader::runtime::Viewport;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use librashader::runtime::{Size, Viewport};
|
||||
use librashader_runtime::image::{Image, PixelFormat, UVDirection, BGRA8};
|
||||
use objc2::ffi::NSUInteger;
|
||||
use objc2::rc::Retained;
|
||||
|
@ -31,10 +31,15 @@ impl RenderTest for Metal {
|
|||
Metal::new(path)
|
||||
}
|
||||
|
||||
fn image_size(&self) -> Size<u32> {
|
||||
self.image_bytes.size
|
||||
}
|
||||
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
output_size: Option<Size<u32>>,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
frame_options: Option<CommonFrameOptions>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
|
@ -59,12 +64,14 @@ impl RenderTest for Metal {
|
|||
setter(filter_chain.parameters());
|
||||
}
|
||||
|
||||
let output_size = output_size.unwrap_or(self.image_bytes.size);
|
||||
|
||||
let render_texture = unsafe {
|
||||
let texture_descriptor =
|
||||
MTLTextureDescriptor::texture2DDescriptorWithPixelFormat_width_height_mipmapped(
|
||||
MTLPixelFormat::BGRA8Unorm,
|
||||
self.image_bytes.size.width as NSUInteger,
|
||||
self.image_bytes.size.height as NSUInteger,
|
||||
output_size.width as NSUInteger,
|
||||
output_size.height as NSUInteger,
|
||||
false,
|
||||
);
|
||||
|
||||
|
@ -113,18 +120,19 @@ impl RenderTest for Metal {
|
|||
let region = MTLRegion {
|
||||
origin: MTLOrigin { x: 0, y: 0, z: 0 },
|
||||
size: MTLSize {
|
||||
width: self.image_bytes.size.width as usize,
|
||||
height: self.image_bytes.size.height as usize,
|
||||
width: output_size.width as usize,
|
||||
height: output_size.height as usize,
|
||||
depth: 1,
|
||||
},
|
||||
};
|
||||
|
||||
unsafe {
|
||||
// should be the same size
|
||||
let mut buffer = vec![0u8; self.image_bytes.bytes.len()];
|
||||
let mut buffer =
|
||||
vec![0u8; output_size.width as usize * output_size.height as usize * 4];
|
||||
render_texture.getBytes_bytesPerRow_fromRegion_mipmapLevel(
|
||||
NonNull::new(buffer.as_mut_ptr().cast()).unwrap(),
|
||||
4 * self.image_bytes.size.width as usize,
|
||||
4 * output_size.width as usize,
|
||||
region,
|
||||
0,
|
||||
);
|
||||
|
|
|
@ -7,8 +7,8 @@ use gpu_allocator::MemoryLocation;
|
|||
use image::RgbaImage;
|
||||
use librashader::presets::ShaderPreset;
|
||||
use librashader::runtime::vk::{FilterChain, FilterChainOptions, FrameOptions, VulkanImage};
|
||||
use librashader::runtime::Viewport;
|
||||
use librashader::runtime::{FilterChainParameters, RuntimeParameters};
|
||||
use librashader::runtime::{Size, Viewport};
|
||||
use librashader_runtime::image::{Image, UVDirection, BGRA8};
|
||||
use std::path::Path;
|
||||
|
||||
|
@ -32,10 +32,15 @@ impl RenderTest for Vulkan {
|
|||
Vulkan::new(path)
|
||||
}
|
||||
|
||||
fn image_size(&self) -> Size<u32> {
|
||||
self.image_bytes.size
|
||||
}
|
||||
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
output_size: Option<Size<u32>>,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
frame_options: Option<CommonFrameOptions>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
|
@ -58,7 +63,7 @@ impl RenderTest for Vulkan {
|
|||
let image_info = vk::ImageCreateInfo::default()
|
||||
.image_type(vk::ImageType::TYPE_2D)
|
||||
.format(vk::Format::B8G8R8A8_UNORM)
|
||||
.extent(self.image_bytes.size.into())
|
||||
.extent(output_size.map_or(self.image_bytes.size.into(), |size| size.into()))
|
||||
.mip_levels(1)
|
||||
.array_layers(1)
|
||||
.samples(vk::SampleCountFlags::TYPE_1)
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::render::{CommonFrameOptions, RenderTest};
|
|||
use anyhow::anyhow;
|
||||
use image::RgbaImage;
|
||||
use librashader::runtime::wgpu::*;
|
||||
use librashader::runtime::Viewport;
|
||||
use librashader::runtime::{Size, Viewport};
|
||||
use librashader_runtime::image::{Image, UVDirection};
|
||||
use std::io::{Cursor, Write};
|
||||
use std::ops::DerefMut;
|
||||
|
@ -23,7 +23,7 @@ pub struct Wgpu {
|
|||
_adapter: Adapter,
|
||||
device: Arc<Device>,
|
||||
queue: Arc<Queue>,
|
||||
_image: Image,
|
||||
image: Image,
|
||||
texture: Arc<Texture>,
|
||||
}
|
||||
|
||||
|
@ -56,10 +56,15 @@ impl RenderTest for Wgpu {
|
|||
Wgpu::new(path)
|
||||
}
|
||||
|
||||
fn image_size(&self) -> Size<u32> {
|
||||
self.image.size
|
||||
}
|
||||
|
||||
fn render_with_preset_and_params(
|
||||
&mut self,
|
||||
preset: ShaderPreset,
|
||||
frame_count: usize,
|
||||
output_size: Option<Size<u32>>,
|
||||
param_setter: Option<&dyn Fn(&RuntimeParameters)>,
|
||||
frame_options: Option<CommonFrameOptions>,
|
||||
) -> anyhow::Result<image::RgbaImage> {
|
||||
|
@ -82,7 +87,7 @@ impl RenderTest for Wgpu {
|
|||
|
||||
let output_tex = self.device.create_texture(&TextureDescriptor {
|
||||
label: None,
|
||||
size: self.texture.size(),
|
||||
size: output_size.map_or(self.texture.size(), |size| size.into()),
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
dimension: TextureDimension::D2,
|
||||
|
@ -219,7 +224,7 @@ impl Wgpu {
|
|||
_adapter: adapter,
|
||||
device: Arc::new(device),
|
||||
queue: Arc::new(queue),
|
||||
_image: image,
|
||||
image: image,
|
||||
texture: Arc::new(texture),
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue