Make hue saturation node work on the gpu + make f32 default for user inputs

This commit is contained in:
Dennis Kobert
2023-06-18 05:51:11 -07:00
committed by Keavon Chambers
parent fea9f8ea24
commit 4abad688a2
21 changed files with 235 additions and 217 deletions
@@ -35,6 +35,7 @@ async fn main() {
}
async fn post_compile_spirv(State(state): State<Arc<AppState>>, Json(compile_request): Json<CompileRequest>) -> Result<Vec<u8>, StatusCode> {
println!("compile request: {:?}", compile_request);
if let Some(result) = state.cache.read().unwrap().get(&compile_request) {
return result.clone();
}
@@ -44,6 +45,9 @@ async fn post_compile_spirv(State(state): State<Arc<AppState>>, Json(compile_req
eprintln!("compilation failed: {}", e);
StatusCode::INTERNAL_SERVER_ERROR
});
if result.is_err() {
return result;
}
state.cache.write().unwrap().insert(compile_request, result.clone());
result
}
+62 -62
View File
@@ -229,7 +229,7 @@ pub struct LevelsNode<InputStart, InputMid, InputEnd, OutputStart, OutputEnd> {
// From https://stackoverflow.com/questions/39510072/algorithm-for-adjustment-of-image-levels
#[node_macro::node_fn(LevelsNode)]
fn levels_node(color: Color, input_start: f64, input_mid: f64, input_end: f64, output_start: f64, output_end: f64) -> Color {
fn levels_node(color: Color, input_start: f32, input_mid: f32, input_end: f32, output_start: f32, output_end: f32) -> Color {
let color = color.to_gamma_srgb();
// Input Range (Range: 0-1)
@@ -286,7 +286,7 @@ pub struct GrayscaleNode<Tint, Reds, Yellows, Greens, Cyans, Blues, Magentas> {
// From <https://stackoverflow.com/a/55233732/775283>
// Works the same for gamma and linear color
#[node_macro::node_fn(GrayscaleNode)]
fn grayscale_color_node(color: Color, tint: Color, reds: f64, yellows: f64, greens: f64, cyans: f64, blues: f64, magentas: f64) -> Color {
fn grayscale_color_node(color: Color, tint: Color, reds: f32, yellows: f32, greens: f32, cyans: f32, blues: f32, magentas: f32) -> Color {
let color = color.to_gamma_srgb();
let reds = reds as f32 / 100.;
@@ -329,7 +329,7 @@ pub struct HueSaturationNode<Hue, Saturation, Lightness> {
}
#[node_macro::node_fn(HueSaturationNode)]
fn hue_shift_color_node(color: Color, hue_shift: f64, saturation_shift: f64, lightness_shift: f64) -> Color {
fn hue_shift_color_node(color: Color, hue_shift: f32, saturation_shift: f32, lightness_shift: f32) -> Color {
let color = color.to_gamma_srgb();
let [hue, saturation, lightness, alpha] = color.to_hsla();
@@ -379,7 +379,7 @@ pub struct ThresholdNode<MinLuminance, MaxLuminance, LuminanceCalc> {
}
#[node_macro::node_fn(ThresholdNode)]
fn threshold_node(color: Color, min_luminance: f64, max_luminance: f64, luminance_calc: LuminanceCalculation) -> Color {
fn threshold_node(color: Color, min_luminance: f32, max_luminance: f32, luminance_calc: LuminanceCalculation) -> Color {
let min_luminance = Color::srgb_to_linear(min_luminance as f32 / 100.);
let max_luminance = Color::srgb_to_linear(max_luminance as f32 / 100.);
@@ -405,7 +405,7 @@ pub struct BlendNode<BlendMode, Opacity> {
}
#[node_macro::node_fn(BlendNode)]
fn blend_node(input: (Color, Color), blend_mode: BlendMode, opacity: f64) -> Color {
fn blend_node(input: (Color, Color), blend_mode: BlendMode, opacity: f32) -> Color {
blend_colors(input.0, input.1, blend_mode, opacity as f32 / 100.)
}
@@ -461,7 +461,7 @@ pub struct VibranceNode<Vibrance> {
// Modified from https://stackoverflow.com/questions/33966121/what-is-the-algorithm-for-vibrance-filters
// The results of this implementation are very close to correct, but not quite perfect
#[node_macro::node_fn(VibranceNode)]
fn vibrance_node(color: Color, vibrance: f64) -> Color {
fn vibrance_node(color: Color, vibrance: f32) -> Color {
let vibrance = vibrance as f32 / 100.;
// Slow the effect down by half when it's negative, since artifacts begin appearing past -50%.
// So this scales the 0% to -50% range to 0% to -100%.
@@ -553,22 +553,22 @@ pub struct ChannelMixerNode<Monochrome, MonochromeR, MonochromeG, MonochromeB, M
fn channel_mixer_node(
color: Color,
monochrome: bool,
monochrome_r: f64,
monochrome_g: f64,
monochrome_b: f64,
monochrome_c: f64,
red_r: f64,
red_g: f64,
red_b: f64,
red_c: f64,
green_r: f64,
green_g: f64,
green_b: f64,
green_c: f64,
blue_r: f64,
blue_g: f64,
blue_b: f64,
blue_c: f64,
monochrome_r: f32,
monochrome_g: f32,
monochrome_b: f32,
monochrome_c: f32,
red_r: f32,
red_g: f32,
red_b: f32,
red_c: f32,
green_r: f32,
green_g: f32,
green_b: f32,
green_c: f32,
blue_r: f32,
blue_g: f32,
blue_b: f32,
blue_c: f32,
) -> Color {
let color = color.to_gamma_srgb();
@@ -690,42 +690,42 @@ pub struct SelectiveColorNode<Absolute, RC, RM, RY, RK, YC, YM, YY, YK, GC, GM,
fn selective_color_node(
color: Color,
mode: RelativeAbsolute,
r_c: f64,
r_m: f64,
r_y: f64,
r_k: f64,
y_c: f64,
y_m: f64,
y_y: f64,
y_k: f64,
g_c: f64,
g_m: f64,
g_y: f64,
g_k: f64,
c_c: f64,
c_m: f64,
c_y: f64,
c_k: f64,
b_c: f64,
b_m: f64,
b_y: f64,
b_k: f64,
m_c: f64,
m_m: f64,
m_y: f64,
m_k: f64,
w_c: f64,
w_m: f64,
w_y: f64,
w_k: f64,
n_c: f64,
n_m: f64,
n_y: f64,
n_k: f64,
k_c: f64,
k_m: f64,
k_y: f64,
k_k: f64,
r_c: f32,
r_m: f32,
r_y: f32,
r_k: f32,
y_c: f32,
y_m: f32,
y_y: f32,
y_k: f32,
g_c: f32,
g_m: f32,
g_y: f32,
g_k: f32,
c_c: f32,
c_m: f32,
c_y: f32,
c_k: f32,
b_c: f32,
b_m: f32,
b_y: f32,
b_k: f32,
m_c: f32,
m_m: f32,
m_y: f32,
m_k: f32,
w_c: f32,
w_m: f32,
w_y: f32,
w_k: f32,
n_c: f32,
n_m: f32,
n_y: f32,
n_k: f32,
k_c: f32,
k_m: f32,
k_y: f32,
k_k: f32,
) -> Color {
let color = color.to_gamma_srgb();
@@ -775,7 +775,7 @@ fn selective_color_node(
// Skip this color parameter group...
// ...if it's unchanged from the default of zero offset on all CMYK paramters, or...
// ...if this pixel's color isn't in the range affected by this color parameter group
if (c < f64::EPSILON && m < f64::EPSILON && y < f64::EPSILON && k < f64::EPSILON) || (!pixel_color_range(color_parameter_group)) {
if (c < f32::EPSILON && m < f32::EPSILON && y < f32::EPSILON && k < f32::EPSILON) || (!pixel_color_range(color_parameter_group)) {
return acc;
}
@@ -807,7 +807,7 @@ pub struct OpacityNode<O> {
}
#[node_macro::node_fn(OpacityNode)]
fn image_opacity(color: Color, opacity_multiplier: f64) -> Color {
fn image_opacity(color: Color, opacity_multiplier: f32) -> Color {
let opacity_multiplier = opacity_multiplier as f32 / 100.;
Color::from_rgbaf32_unchecked(color.r(), color.g(), color.b(), color.a() * opacity_multiplier)
}
@@ -820,7 +820,7 @@ pub struct PosterizeNode<P> {
// Based on http://www.axiomx.com/posterize.htm
// This algorithm is perfectly accurate.
#[node_macro::node_fn(PosterizeNode)]
fn posterize(color: Color, posterize_value: f64) -> Color {
fn posterize(color: Color, posterize_value: f32) -> Color {
let color = color.to_gamma_srgb();
let posterize_value = posterize_value as f32;
@@ -841,7 +841,7 @@ pub struct ExposureNode<Exposure, Offset, GammaCorrection> {
// Based on https://geraldbakker.nl/psnumbers/exposure.html
#[node_macro::node_fn(ExposureNode)]
fn exposure(color: Color, exposure: f64, offset: f64, gamma_correction: f64) -> Color {
fn exposure(color: Color, exposure: f32, offset: f32, gamma_correction: f32) -> Color {
let adjusted = color
// Exposure
.map_rgb(|c: f32| c * 2_f32.powf(exposure as f32))
+2 -2
View File
@@ -15,7 +15,7 @@ pub struct TextGenerator<Text, FontName, Size> {
}
#[node_fn(TextGenerator)]
fn generate_text<'a: 'input, T>(editor: EditorApi<'a, T>, text: String, font_name: Font, font_size: f64) -> crate::vector::VectorData {
fn generate_text<'a: 'input, T>(editor: EditorApi<'a, T>, text: String, font_name: Font, font_size: f32) -> crate::vector::VectorData {
let buzz_face = editor.font_cache.get(&font_name).map(|data| load_face(data));
crate::vector::VectorData::from_subpaths(to_path(&text, buzz_face, font_size, None))
crate::vector::VectorData::from_subpaths(to_path(&text, buzz_face, font_size as f64, None))
}
+2 -2
View File
@@ -78,10 +78,10 @@ pub struct TransformNode<Translation, Rotation, Scale, Shear, Pivot> {
}
#[node_macro::node_fn(TransformNode)]
pub(crate) fn transform_vector_data<Data: TransformMut>(mut data: Data, translate: DVec2, rotate: f64, scale: DVec2, shear: DVec2, pivot: DVec2) -> Data {
pub(crate) fn transform_vector_data<Data: TransformMut>(mut data: Data, translate: DVec2, rotate: f32, scale: DVec2, shear: DVec2, pivot: DVec2) -> Data {
let pivot = DAffine2::from_translation(data.local_pivot(pivot));
let modification = pivot * DAffine2::from_scale_angle_translation(scale, rotate, translate) * DAffine2::from_cols_array(&[1., shear.y, shear.x, 1., 0., 0.]) * pivot.inverse();
let modification = pivot * DAffine2::from_scale_angle_translation(scale, rotate as f64, translate) * DAffine2::from_cols_array(&[1., shear.y, shear.x, 1., 0., 0.]) * pivot.inverse();
let data_transform = data.transform_mut();
*data_transform = modification * (*data_transform);
+6 -6
View File
@@ -53,21 +53,21 @@ pub struct SetStrokeNode<Color, Weight, DashLengths, DashOffset, LineCap, LineJo
fn set_vector_data_stroke(
mut vector_data: VectorData,
color: Option<Color>,
weight: f64,
weight: f32,
dash_lengths: Vec<f32>,
dash_offset: f64,
dash_offset: f32,
line_cap: super::style::LineCap,
line_join: super::style::LineJoin,
miter_limit: f64,
miter_limit: f32,
) -> VectorData {
vector_data.style.set_stroke(Stroke {
color,
weight,
weight: weight as f64,
dash_lengths,
dash_offset,
dash_offset: dash_offset as f64,
line_cap,
line_join,
line_join_miter_limit: miter_limit,
line_join_miter_limit: miter_limit as f64,
});
vector_data
}
+5 -4
View File
@@ -121,7 +121,7 @@ impl SpirVCompiler for GpuCompiler {
pub fn serialize_gpu(networks: &[ProtoNetwork], io: &ShaderIO) -> anyhow::Result<String> {
fn nid(id: &u64) -> String {
format!("n{id}")
format!("n{id:0x}")
}
dbg!(&io);
@@ -216,9 +216,10 @@ pub fn compile(dir: &Path) -> Result<spirv_builder::CompileResult, spirv_builder
.release(true)
.spirv_metadata(SpirvMetadata::Full)
.capability(spirv_builder::Capability::Float64)
.extra_arg("no-early-report-zombies")
.extra_arg("no-infer-storage-classes")
.extra_arg("spirt-passes=qptr")
//.extra_arg("no-early-report-zombies")
//.extra_arg("no-infer-storage-classes")
//.extra_arg("spirt-passes=qptr,reduce")
.extra_arg("spirt-passes=reduce")
.build()?;
Ok(result)
+11 -5
View File
@@ -654,10 +654,13 @@ impl NodeNetwork {
/// Recursively dissolve non-primitive document nodes and return a single flattened network of nodes.
pub fn flatten_with_fns(&mut self, node: NodeId, map_ids: impl Fn(NodeId, NodeId) -> NodeId + Copy, gen_id: impl Fn() -> NodeId + Copy) {
let (id, mut node) = self
self.resolve_extract_nodes();
let Some((id, mut node)) = self
.nodes
.remove_entry(&node)
.unwrap_or_else(|| panic!("The node which was supposed to be flattened does not exist in the network, id {} network {:#?}", node, self));
.remove_entry(&node) else {
warn!("The node which was supposed to be flattened does not exist in the network, id {} network {:#?}", node, self);
return;
};
if self.disabled.contains(&id) {
node.implementation = DocumentNodeImplementation::Unresolved("graphene_core::ops::IdNode".into());
@@ -665,7 +668,7 @@ impl NodeNetwork {
self.nodes.insert(id, node);
return;
}
log::debug!("Flattening node {:?}", &node);
log::debug!("Flattening node {:?}", &node.name);
// replace value inputs with value nodes
for input in &mut node.inputs {
@@ -846,7 +849,10 @@ impl NodeNetwork {
let mut input_node = self.nodes.remove(&node_id).unwrap();
node.implementation = DocumentNodeImplementation::Unresolved("graphene_core::value::ClonedNode".into());
if let Some(input) = input_node.inputs.get_mut(0) {
*input = NodeInput::Network(input.ty());
*input = match &input {
NodeInput::Node { .. } => NodeInput::Network(generic!(T)),
ni => NodeInput::Network(ni.ty()),
};
}
for input in input_node.inputs.iter_mut() {
@@ -9,9 +9,8 @@ pub struct Compiler {}
impl Compiler {
pub fn compile(&self, mut network: NodeNetwork, resolve_inputs: bool) -> impl Iterator<Item = ProtoNetwork> {
let node_ids = network.nodes.keys().copied().collect::<Vec<_>>();
println!("flattening");
network.resolve_extract_nodes();
let node_ids = network.nodes.keys().copied().collect::<Vec<_>>();
for id in node_ids {
network.flatten(id);
}
+1 -1
View File
@@ -181,7 +181,7 @@ impl Hash for ConstructionArgs {
impl ConstructionArgs {
pub fn new_function_args(&self) -> Vec<String> {
match self {
ConstructionArgs::Nodes(nodes) => nodes.iter().map(|n| format!("&n{}", n.0)).collect(),
ConstructionArgs::Nodes(nodes) => nodes.iter().map(|n| format!("n{:0x}", n.0)).collect(),
ConstructionArgs::Value(value) => vec![value.to_primitive_string()],
ConstructionArgs::Inline(inline) => vec![inline.expr.clone()],
}
+1
View File
@@ -17,6 +17,7 @@ default = ["wgpu"]
wgpu = ["wgpu-executor", "gpu", "graphene-std/wgpu"]
wayland = ["graphene-std/wayland"]
profiling = ["wgpu-executor/profiling"]
passthrough = ["wgpu-executor/passthrough"]
[dependencies]
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -601,7 +601,7 @@
{
"Value": {
"tagged_value": {
"F64": 0.0
"F32": 0.0
},
"exposed": false
}
@@ -191,10 +191,10 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
register_node!(graphene_core::ops::AddParameterNode<_>, input: &u32, params: [u32]),
register_node!(graphene_core::ops::AddParameterNode<_>, input: u32, params: [&u32]),
register_node!(graphene_core::ops::AddParameterNode<_>, input: &u32, params: [&u32]),
register_node!(graphene_core::ops::AddParameterNode<_>, input: f64, params: [f64]),
register_node!(graphene_core::ops::AddParameterNode<_>, input: &f64, params: [f64]),
register_node!(graphene_core::ops::AddParameterNode<_>, input: f64, params: [&f64]),
register_node!(graphene_core::ops::AddParameterNode<_>, input: &f64, params: [&f64]),
register_node!(graphene_core::ops::AddParameterNode<_>, input: f32, params: [f32]),
register_node!(graphene_core::ops::AddParameterNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::AddParameterNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::AddParameterNode<_>, input: &f32, params: [&f32]),
register_node!(graphene_core::ops::SomeNode, input: WasmEditorApi, params: []),
async_node!(graphene_core::ops::IntoNode<_, ImageFrame<SRGBA8>>, input: ImageFrame<Color>, output: ImageFrame<SRGBA8>, params: []),
async_node!(graphene_core::ops::IntoNode<_, ImageFrame<Color>>, input: ImageFrame<SRGBA8>, output: ImageFrame<Color>, params: []),
@@ -355,7 +355,7 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
raster_node!(graphene_core::raster::ExtractChannelNode<_>, params: [RedGreenBlue]),
raster_node!(graphene_core::raster::ExtractAlphaNode<>, params: []),
raster_node!(graphene_core::raster::ExtractOpaqueNode<>, params: []),
raster_node!(graphene_core::raster::LevelsNode<_, _, _, _, _>, params: [f64, f64, f64, f64, f64]),
raster_node!(graphene_core::raster::LevelsNode<_, _, _, _, _>, params: [f32, f32, f32, f32, f32]),
register_node!(graphene_std::image_segmentation::ImageSegmentationNode<_>, input: ImageFrame<Color>, params: [ImageFrame<Color>]),
register_node!(graphene_core::raster::IndexNode<_>, input: Vec<ImageFrame<Color>>, params: [u32]),
vec![(
@@ -364,7 +364,7 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
Box::pin(async move {
let image: DowncastBothNode<(), ImageFrame<Color>> = DowncastBothNode::new(args[0].clone());
let blend_mode: DowncastBothNode<(), BlendMode> = DowncastBothNode::new(args[1].clone());
let opacity: DowncastBothNode<(), f64> = DowncastBothNode::new(args[2].clone());
let opacity: DowncastBothNode<(), f32> = DowncastBothNode::new(args[2].clone());
let blend_node = graphene_core::raster::BlendNode::new(CopiedNode::new(blend_mode.eval(()).await), CopiedNode::new(opacity.eval(()).await));
let node = graphene_std::raster::BlendImageNode::new(image, blend_node);
let any: DynAnyNode<ImageFrame<Color>, _, _> = graphene_std::any::DynAnyNode::new(node);
@@ -374,21 +374,21 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
NodeIOTypes::new(
concrete!(ImageFrame<Color>),
concrete!(ImageFrame<Color>),
vec![fn_type!(ImageFrame<Color>), fn_type!(BlendMode), fn_type!(f64)],
vec![fn_type!(ImageFrame<Color>), fn_type!(BlendMode), fn_type!(f32)],
),
)],
raster_node!(graphene_core::raster::GrayscaleNode<_, _, _, _, _, _, _>, params: [Color, f64, f64, f64, f64, f64, f64]),
raster_node!(graphene_core::raster::HueSaturationNode<_, _, _>, params: [f64, f64, f64]),
raster_node!(graphene_core::raster::GrayscaleNode<_, _, _, _, _, _, _>, params: [Color, f32, f32, f32, f32, f32, f32]),
raster_node!(graphene_core::raster::HueSaturationNode<_, _, _>, params: [f32, f32, f32]),
raster_node!(graphene_core::raster::InvertRGBNode, params: []),
raster_node!(graphene_core::raster::ThresholdNode<_, _, _>, params: [f64, f64, LuminanceCalculation]),
raster_node!(graphene_core::raster::VibranceNode<_>, params: [f64]),
raster_node!(graphene_core::raster::ThresholdNode<_, _, _>, params: [f32, f32, LuminanceCalculation]),
raster_node!(graphene_core::raster::VibranceNode<_>, params: [f32]),
raster_node!(
graphene_core::raster::ChannelMixerNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _>,
params: [bool, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64]
params: [bool, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32]
),
raster_node!(
graphene_core::raster::SelectiveColorNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _>,
params: [RelativeAbsolute, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64]
params: [RelativeAbsolute, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32]
),
vec![(
NodeIdentifier::new("graphene_core::raster::BrightnessContrastNode<_, _, _>"),
@@ -396,9 +396,9 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
Box::pin(async move {
use graphene_core::raster::brightness_contrast::*;
let brightness: DowncastBothNode<(), f64> = DowncastBothNode::new(args[0].clone());
let brightness: DowncastBothNode<(), f32> = DowncastBothNode::new(args[0].clone());
let brightness = ClonedNode::new(brightness.eval(()).await as f32);
let contrast: DowncastBothNode<(), f64> = DowncastBothNode::new(args[1].clone());
let contrast: DowncastBothNode<(), f32> = DowncastBothNode::new(args[1].clone());
let contrast = ClonedNode::new(contrast.eval(()).await as f32);
let use_legacy: DowncastBothNode<(), bool> = DowncastBothNode::new(args[2].clone());
@@ -417,11 +417,11 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
}
})
},
NodeIOTypes::new(concrete!(ImageFrame<Color>), concrete!(ImageFrame<Color>), vec![fn_type!(f64), fn_type!(f64), fn_type!(bool)]),
NodeIOTypes::new(concrete!(ImageFrame<Color>), concrete!(ImageFrame<Color>), vec![fn_type!(f32), fn_type!(f32), fn_type!(bool)]),
)],
raster_node!(graphene_core::raster::OpacityNode<_>, params: [f64]),
raster_node!(graphene_core::raster::PosterizeNode<_>, params: [f64]),
raster_node!(graphene_core::raster::ExposureNode<_, _, _>, params: [f64, f64, f64]),
raster_node!(graphene_core::raster::OpacityNode<_>, params: [f32]),
raster_node!(graphene_core::raster::PosterizeNode<_>, params: [f32]),
raster_node!(graphene_core::raster::ExposureNode<_, _, _>, params: [f32, f32, f32]),
register_node!(graphene_core::memo::LetNode<_>, input: Option<ImageFrame<Color>>, params: []),
register_node!(graphene_core::memo::LetNode<_>, input: Option<WasmEditorApi>, params: []),
async_node!(graphene_core::memo::EndLetNode<_>, input: WasmEditorApi, output: ImageFrame<Color>, params: [ImageFrame<Color>]),
@@ -479,18 +479,18 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
vec![
fn_type!(WasmEditorApi),
fn_type!(ImaginateController),
fn_type!(f64),
fn_type!(f32),
fn_type!(Option<DVec2>),
fn_type!(u32),
fn_type!(ImaginateSamplingMethod),
fn_type!(f64),
fn_type!(f32),
fn_type!(String),
fn_type!(String),
fn_type!(bool),
fn_type!(f64),
fn_type!(f32),
fn_type!(Option<Vec<u64>>),
fn_type!(bool),
fn_type!(f64),
fn_type!(f32),
fn_type!(ImaginateMaskStartingFill),
fn_type!(bool),
fn_type!(bool),
@@ -516,22 +516,22 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
raster_node!(graphene_core::quantization::QuantizeNode<_>, params: [QuantizationChannels]),
raster_node!(graphene_core::quantization::DeQuantizeNode<_>, params: [QuantizationChannels]),
register_node!(graphene_core::ops::CloneNode<_>, input: &QuantizationChannels, params: []),
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: VectorData, params: [DVec2, f64, DVec2, DVec2, DVec2]),
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: ImageFrame<Color>, params: [DVec2, f64, DVec2, DVec2, DVec2]),
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: WasmSurfaceHandleFrame, params: [DVec2, f64, DVec2, DVec2, DVec2]),
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: VectorData, params: [DVec2, f32, DVec2, DVec2, DVec2]),
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: ImageFrame<Color>, params: [DVec2, f32, DVec2, DVec2, DVec2]),
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: WasmSurfaceHandleFrame, params: [DVec2, f32, DVec2, DVec2, DVec2]),
register_node!(graphene_core::transform::SetTransformNode<_>, input: VectorData, params: [VectorData]),
register_node!(graphene_core::transform::SetTransformNode<_>, input: ImageFrame<Color>, params: [ImageFrame<Color>]),
register_node!(graphene_core::transform::SetTransformNode<_>, input: VectorData, params: [DAffine2]),
register_node!(graphene_core::transform::SetTransformNode<_>, input: ImageFrame<Color>, params: [DAffine2]),
register_node!(graphene_core::vector::SetFillNode<_, _, _, _, _, _, _>, input: VectorData, params: [graphene_core::vector::style::FillType, Option<graphene_core::Color>, graphene_core::vector::style::GradientType, DVec2, DVec2, DAffine2, Vec<(f64, Option<graphene_core::Color>)>]),
register_node!(graphene_core::vector::SetStrokeNode<_, _, _, _, _, _, _>, input: VectorData, params: [Option<graphene_core::Color>, f64, Vec<f32>, f64, graphene_core::vector::style::LineCap, graphene_core::vector::style::LineJoin, f64]),
register_node!(graphene_core::vector::SetStrokeNode<_, _, _, _, _, _, _>, input: VectorData, params: [Option<graphene_core::Color>, f32, Vec<f32>, f32, graphene_core::vector::style::LineCap, graphene_core::vector::style::LineJoin, f32]),
register_node!(graphene_core::vector::generator_nodes::UnitCircleGenerator, input: (), params: []),
register_node!(
graphene_core::vector::generator_nodes::PathGenerator<_>,
input: Vec<graphene_core::vector::bezier_rs::Subpath<graphene_core::uuid::ManipulatorGroupId>>,
params: [Vec<graphene_core::uuid::ManipulatorGroupId>]
),
register_node!(graphene_core::text::TextGenerator<_, _, _>, input: WasmEditorApi, params: [String, graphene_core::text::Font, f64]),
register_node!(graphene_core::text::TextGenerator<_, _, _>, input: WasmEditorApi, params: [String, graphene_core::text::Font, f32]),
register_node!(graphene_std::brush::VectorPointsNode, input: VectorData, params: []),
register_node!(graphene_core::ExtractImageFrame, input: WasmEditorApi, params: []),
register_node!(graphene_core::ConstructLayerNode<_, _, _, _, _, _, _>, input: graphene_core::vector::VectorData, params: [String, BlendMode, f32, bool, bool, bool, graphene_core::GraphicGroup]),
+1
View File
@@ -7,6 +7,7 @@ license = "MIT OR Apache-2.0"
[features]
default = []
profiling = ["nvtx"]
passthrough = []
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+3 -4
View File
@@ -19,17 +19,16 @@ impl Context {
// `request_adapter` instantiates the general connection to the GPU
let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions::default()).await?;
//let limits = adapter.limits();
//log::trace!("Adapter limits: {:?}", limits);
// `request_device` instantiates the feature specific connection to the GPU, defining some parameters,
// `features` being the available features.
let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
label: None,
#[cfg(not(feature = "passthrough"))]
features: wgpu::Features::empty(),
#[cfg(feature = "passthrough")]
features: wgpu::Features::SPIRV_SHADER_PASSTHROUGH,
limits: Default::default(),
},
None,
+8
View File
@@ -118,10 +118,18 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
type Window = Arc<winit::window::Window>;
fn load_shader(&self, shader: Shader) -> Result<Self::ShaderHandle> {
#[cfg(not(feature = "passthrough"))]
let shader_module = self.context.device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some(shader.name),
source: wgpu::ShaderSource::SpirV(shader.source),
});
#[cfg(feature = "passthrough")]
let shader_module = unsafe {
self.context.device.create_shader_module_spirv(&wgpu::ShaderModuleDescriptorSpirV {
label: Some(shader.name),
source: shader.source,
})
};
Ok(ShaderModuleWrapper(shader_module))
}