From 5b6db0a762d2d7b5e6cd46114719f2e647f5d42a Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Thu, 8 Jun 2023 10:13:19 +0200 Subject: [PATCH] Add document nodes for gpu pipeline nodes (#1292) * Add document nodes for gpu pipeline nodes * Load existing frame instead of clearing it * Feature gate gpu imports --- Cargo.lock | 2 + editor/Cargo.toml | 4 +- .../document_node_types.rs | 468 +++++++++++++++++- node-graph/gpu-executor/src/lib.rs | 14 +- node-graph/graph-craft/src/proto.rs | 8 +- .../interpreted-executor/src/node_registry.rs | 5 + node-graph/wgpu-executor/src/lib.rs | 4 +- 7 files changed, 493 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b030e83..43950867 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1872,6 +1872,7 @@ dependencies = [ "env_logger", "futures", "glam", + "gpu-executor", "graph-craft", "graphene-core", "graphene-std", @@ -1889,6 +1890,7 @@ dependencies = [ "specta", "test-case", "thiserror", + "wgpu-executor", ] [[package]] diff --git a/editor/Cargo.toml b/editor/Cargo.toml index 18835e3b..99ea74d9 100644 --- a/editor/Cargo.toml +++ b/editor/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/GraphiteEditor/Graphite" license = "Apache-2.0" [features] -gpu = ["interpreted-executor/gpu", "graphene-std/gpu", "graphene-core/gpu"] +gpu = ["interpreted-executor/gpu", "graphene-std/gpu", "graphene-core/gpu", "wgpu-executor", "gpu-executor"] quantization = [ "graphene-std/quantization", "interpreted-executor/quantization", @@ -40,6 +40,8 @@ image = { version = "0.24", default-features = false, features = [ "png", ] } graph-craft = { path = "../node-graph/graph-craft" } +wgpu-executor = { path = "../node-graph/wgpu-executor", optional = true } +gpu-executor = { path = "../node-graph/gpu-executor", optional = true } interpreted-executor = { path = "../node-graph/interpreted-executor" } dyn-any = { path = "../libraries/dyn-any" } graphene-core = { path = "../node-graph/gcore" } diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/document_node_types.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/document_node_types.rs index fa0cb04e..25a84e05 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/document_node_types.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/document_node_types.rs @@ -8,15 +8,21 @@ use graph_craft::document::value::*; use graph_craft::document::*; use graph_craft::imaginate_input::ImaginateSamplingMethod; use graph_craft::NodeIdentifier; +#[cfg(feature = "gpu")] +use graphene_core::application_io::SurfaceHandle; use graphene_core::raster::brush_cache::BrushCache; use graphene_core::raster::{BlendMode, Color, Image, ImageFrame, LuminanceCalculation, RedGreenBlue, RelativeAbsolute, SelectiveColorChoice}; use graphene_core::text::Font; use graphene_core::vector::VectorData; use graphene_core::*; +#[cfg(feature = "gpu")] +use gpu_executor::*; use graphene_std::wasm_application_io::WasmEditorApi; use once_cell::sync::Lazy; use std::collections::VecDeque; +#[cfg(feature = "gpu")] +use wgpu_executor::WgpuExecutor; #[derive(Debug, Clone, PartialEq, Hash)] pub struct DocumentInputType { @@ -743,8 +749,8 @@ fn static_nodes() -> Vec { }, DocumentNode { name: "Create Uniform".to_string(), - inputs: vec![NodeInput::Network(concrete!(f32))], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu-executor::UniformNode<_>")), + inputs: vec![NodeInput::Network(generic!(T)), NodeInput::node(0, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu_executor::UniformNode<_>")), ..Default::default() }, DocumentNode { @@ -776,9 +782,466 @@ fn static_nodes() -> Vec { name: "Uniform", data_type: FrontendGraphDataType::General, }], + properties: node_properties::no_properties, + }, + #[cfg(feature = "gpu")] + DocumentNodeType { + name: "Storage", + category: "Gpu", + identifier: NodeImplementation::DocumentNode(NodeNetwork { + inputs: vec![1, 0], + outputs: vec![NodeOutput::new(2, 0)], + nodes: [ + DocumentNode { + name: "Extract Executor".to_string(), + inputs: vec![NodeInput::Network(concrete!(WasmEditorApi))], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IntoNode<_, &WgpuExecutor>")), + ..Default::default() + }, + DocumentNode { + name: "Create Storage".to_string(), + inputs: vec![NodeInput::Network(concrete!(Vec)), NodeInput::node(0, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu_executor::StorageNode<_>")), + ..Default::default() + }, + DocumentNode { + name: "Cache".to_string(), + inputs: vec![NodeInput::ShortCircut(concrete!(())), NodeInput::node(1, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::memo::MemoNode<_, _>")), + ..Default::default() + }, + ] + .into_iter() + .enumerate() + .map(|(id, node)| (id as NodeId, node)) + .collect(), + ..Default::default() + }), + inputs: vec![ + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::value(TaggedValue::None, true), + }, + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(WasmEditorApi)), + }, + ], + outputs: vec![DocumentOutputType { + name: "Storage", + data_type: FrontendGraphDataType::General, + }], + properties: node_properties::no_properties, + }, + #[cfg(feature = "gpu")] + DocumentNodeType { + name: "CreateOutputBuffer", + category: "Gpu", + identifier: NodeImplementation::DocumentNode(NodeNetwork { + inputs: vec![1, 1, 0], + outputs: vec![NodeOutput::new(2, 0)], + nodes: [ + DocumentNode { + name: "Extract Executor".to_string(), + inputs: vec![NodeInput::Network(concrete!(WasmEditorApi))], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IntoNode<_, &WgpuExecutor>")), + ..Default::default() + }, + DocumentNode { + name: "Create Output Buffer".to_string(), + inputs: vec![NodeInput::Network(concrete!(usize)), NodeInput::node(0, 0), NodeInput::Network(concrete!(Type))], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu_executor::CreateOutputBufferNode<_, _>")), + ..Default::default() + }, + DocumentNode { + name: "Cache".to_string(), + inputs: vec![NodeInput::ShortCircut(concrete!(())), NodeInput::node(1, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::memo::MemoNode<_, _>")), + ..Default::default() + }, + ] + .into_iter() + .enumerate() + .map(|(id, node)| (id as NodeId, node)) + .collect(), + ..Default::default() + }), + inputs: vec![ + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::value(TaggedValue::None, true), + }, + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(WasmEditorApi)), + }, + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::value(TaggedValue::None, true), + }, + ], + outputs: vec![DocumentOutputType { + name: "OutputBuffer", + data_type: FrontendGraphDataType::General, + }], properties: node_properties::input_properties, }, #[cfg(feature = "gpu")] + DocumentNodeType { + name: "CreateComputePass", + category: "Gpu", + identifier: NodeImplementation::DocumentNode(NodeNetwork { + inputs: vec![1, 0, 1, 1], + outputs: vec![NodeOutput::new(2, 0)], + nodes: [ + DocumentNode { + name: "Extract Executor".to_string(), + inputs: vec![NodeInput::Network(concrete!(WasmEditorApi))], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IntoNode<_, &WgpuExecutor>")), + ..Default::default() + }, + DocumentNode { + name: "Create Compute Pass".to_string(), + inputs: vec![ + NodeInput::Network(concrete!(gpu_executor::PipelineLayout)), + NodeInput::node(0, 0), + NodeInput::Network(concrete!(ShaderInput)), + NodeInput::Network(concrete!(gpu_executor::ComputePassDimensions)), + ], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu_executor::CreateComputePassNode<_, _, _>")), + ..Default::default() + }, + DocumentNode { + name: "Cache".to_string(), + inputs: vec![NodeInput::ShortCircut(concrete!(())), NodeInput::node(1, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::memo::MemoNode<_, _>")), + ..Default::default() + }, + ] + .into_iter() + .enumerate() + .map(|(id, node)| (id as NodeId, node)) + .collect(), + ..Default::default() + }), + inputs: vec![ + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(gpu_executor::PipelineLayout)), + }, + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(WasmEditorApi)), + }, + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(ShaderInput)), + }, + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(gpu_executor::ComputePassDimensions)), + }, + ], + outputs: vec![DocumentOutputType { + name: "CommandBuffer", + data_type: FrontendGraphDataType::General, + }], + properties: node_properties::input_properties, + }, + #[cfg(feature = "gpu")] + DocumentNodeType { + name: "CreatePipelineLayout", + category: "Gpu", + identifier: NodeImplementation::proto("gpu_executor::CreatePipelineLayoutNode<_, _, _, _>"), + inputs: vec![ + DocumentInputType { + name: "ShaderHandle", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(::ShaderHandle)), + }, + DocumentInputType { + name: "String", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(String)), + }, + DocumentInputType { + name: "Bindgroup", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(gpu_executor::Bindgroup)), + }, + DocumentInputType { + name: "ArcShaderInput", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(Arc>)), + }, + ], + outputs: vec![DocumentOutputType { + name: "PipelineLayout", + data_type: FrontendGraphDataType::General, + }], + properties: node_properties::input_properties, + }, + #[cfg(feature = "gpu")] + DocumentNodeType { + name: "ExecuteComputePipeline", + category: "Gpu", + identifier: NodeImplementation::DocumentNode(NodeNetwork { + inputs: vec![1, 0], + outputs: vec![NodeOutput::new(2, 0)], + nodes: [ + DocumentNode { + name: "Extract Executor".to_string(), + inputs: vec![NodeInput::Network(concrete!(WasmEditorApi))], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IntoNode<_, &WgpuExecutor>")), + ..Default::default() + }, + DocumentNode { + name: "Execute Compute Pipeline".to_string(), + inputs: vec![NodeInput::Network(concrete!(::CommandBuffer)), NodeInput::node(0, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu_executor::ExecuteComputePipelineNode<_>")), + ..Default::default() + }, + DocumentNode { + name: "Cache".to_string(), + inputs: vec![NodeInput::ShortCircut(concrete!(())), NodeInput::node(1, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::memo::MemoNode<_, _>")), + ..Default::default() + }, + ] + .into_iter() + .enumerate() + .map(|(id, node)| (id as NodeId, node)) + .collect(), + ..Default::default() + }), + inputs: vec![ + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::value(TaggedValue::None, true), + }, + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(WasmEditorApi)), + }, + ], + outputs: vec![DocumentOutputType { + name: "PipelineResult", + data_type: FrontendGraphDataType::General, + }], + properties: node_properties::no_properties, + }, + #[cfg(feature = "gpu")] + DocumentNodeType { + name: "ReadOutputBuffer", + category: "Gpu", + identifier: NodeImplementation::DocumentNode(NodeNetwork { + inputs: vec![1, 0], + outputs: vec![NodeOutput::new(2, 0)], + nodes: [ + DocumentNode { + name: "Extract Executor".to_string(), + inputs: vec![NodeInput::Network(concrete!(WasmEditorApi))], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IntoNode<_, &WgpuExecutor>")), + ..Default::default() + }, + DocumentNode { + name: "Read Output Buffer".to_string(), + inputs: vec![NodeInput::Network(concrete!(Arc>)), NodeInput::node(0, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu_executor::ReadOutputBufferNode<_, _>")), + ..Default::default() + }, + DocumentNode { + name: "Cache".to_string(), + inputs: vec![NodeInput::ShortCircut(concrete!(())), NodeInput::node(1, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::memo::MemoNode<_, _>")), + ..Default::default() + }, + ] + .into_iter() + .enumerate() + .map(|(id, node)| (id as NodeId, node)) + .collect(), + ..Default::default() + }), + inputs: vec![ + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::value(TaggedValue::None, true), + }, + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(WasmEditorApi)), + }, + ], + outputs: vec![DocumentOutputType { + name: "Buffer", + data_type: FrontendGraphDataType::General, + }], + properties: node_properties::no_properties, + }, + #[cfg(feature = "gpu")] + DocumentNodeType { + name: "CreateGpuSurface", + category: "Gpu", + identifier: NodeImplementation::DocumentNode(NodeNetwork { + inputs: vec![0], + outputs: vec![NodeOutput::new(1, 0)], + nodes: [ + DocumentNode { + name: "Create Gpu Surface".to_string(), + inputs: vec![NodeInput::Network(concrete!(WasmEditorApi))], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu_executor::CreateGpuSurfaceNode")), + ..Default::default() + }, + DocumentNode { + name: "Cache".to_string(), + inputs: vec![NodeInput::ShortCircut(concrete!(())), NodeInput::node(0, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::memo::MemoNode<_, _>")), + ..Default::default() + }, + ] + .into_iter() + .enumerate() + .map(|(id, node)| (id as NodeId, node)) + .collect(), + ..Default::default() + }), + inputs: vec![DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(WasmEditorApi)), + }], + outputs: vec![DocumentOutputType { + name: "GpuSurface", + data_type: FrontendGraphDataType::General, + }], + properties: node_properties::no_properties, + }, + #[cfg(feature = "gpu")] + DocumentNodeType { + name: "RenderTexture", + category: "Gpu", + identifier: NodeImplementation::DocumentNode(NodeNetwork { + inputs: vec![1, 1, 0], + outputs: vec![NodeOutput::new(2, 0)], + nodes: [ + DocumentNode { + name: "Extract Executor".to_string(), + inputs: vec![NodeInput::Network(concrete!(WasmEditorApi))], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IntoNode<_, &WgpuExecutor>")), + ..Default::default() + }, + DocumentNode { + name: "Render Texture".to_string(), + inputs: vec![ + NodeInput::Network(concrete!(ShaderInputFrame)), + NodeInput::Network(concrete!(Arc::Surface>>)), + NodeInput::node(0, 0), + ], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu_executor::RenderTextureNode<_, _>")), + ..Default::default() + }, + DocumentNode { + name: "Cache".to_string(), + inputs: vec![NodeInput::ShortCircut(concrete!(())), NodeInput::node(1, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::memo::MemoNode<_, _>")), + ..Default::default() + }, + ] + .into_iter() + .enumerate() + .map(|(id, node)| (id as NodeId, node)) + .collect(), + ..Default::default() + }), + inputs: vec![ + DocumentInputType { + name: "Texture", + data_type: FrontendGraphDataType::General, + default: NodeInput::value(TaggedValue::None, true), + }, + DocumentInputType { + name: "Surface", + data_type: FrontendGraphDataType::General, + default: NodeInput::value(TaggedValue::None, true), + }, + DocumentInputType { + name: "EditorApi", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(WasmEditorApi)), + }, + ], + outputs: vec![DocumentOutputType { + name: "RenderedTexture", + data_type: FrontendGraphDataType::General, + }], + properties: node_properties::no_properties, + }, + #[cfg(feature = "gpu")] + DocumentNodeType { + name: "UploadTexture", + category: "Gpu", + identifier: NodeImplementation::DocumentNode(NodeNetwork { + inputs: vec![1, 0], + outputs: vec![NodeOutput::new(2, 0)], + nodes: [ + DocumentNode { + name: "Extract Executor".to_string(), + inputs: vec![NodeInput::Network(concrete!(WasmEditorApi))], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IntoNode<_, &WgpuExecutor>")), + ..Default::default() + }, + DocumentNode { + name: "Upload Texture".to_string(), + inputs: vec![NodeInput::Network(concrete!(ImageFrame)), NodeInput::node(0, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu_executor::UploadTextureNode<_>")), + ..Default::default() + }, + DocumentNode { + name: "Cache".to_string(), + inputs: vec![NodeInput::ShortCircut(concrete!(())), NodeInput::node(1, 0)], + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::memo::MemoNode<_, _>")), + ..Default::default() + }, + ] + .into_iter() + .enumerate() + .map(|(id, node)| (id as NodeId, node)) + .collect(), + ..Default::default() + }), + inputs: vec![ + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true), + }, + DocumentInputType { + name: "In", + data_type: FrontendGraphDataType::General, + default: NodeInput::Network(concrete!(WasmEditorApi)), + }, + ], + outputs: vec![DocumentOutputType { + name: "Texture", + data_type: FrontendGraphDataType::General, + }], + properties: node_properties::no_properties, + }, + #[cfg(feature = "gpu")] DocumentNodeType { name: "GpuImage", category: "Image Adjustments", @@ -826,7 +1289,6 @@ fn static_nodes() -> Vec { properties: node_properties::no_properties, }, #[cfg(feature = "quantization")] - #[cfg(feature = "quantization")] DocumentNodeType { name: "Generate Quantization", category: "Quantization", diff --git a/node-graph/gpu-executor/src/lib.rs b/node-graph/gpu-executor/src/lib.rs index edf22b9c..825ce6ff 100644 --- a/node-graph/gpu-executor/src/lib.rs +++ b/node-graph/gpu-executor/src/lib.rs @@ -485,10 +485,10 @@ async fn read_output_buffer_node<'a: 'input, E: 'a + GpuExecutor>(buffer: Arc, Io: ApplicationIo>(editor_api: EditorApi<'a, Io>) -> SurfaceHandle { +async fn create_gpu_surface<'a: 'input, E: 'a + GpuExecutor, Io: ApplicationIo>(editor_api: EditorApi<'a, Io>) -> Arc> { let canvas = editor_api.application_io.create_surface(); let executor = editor_api.application_io.gpu_executor().unwrap(); - executor.create_surface(canvas).unwrap() + Arc::new(executor.create_surface(canvas).unwrap()) } pub struct RenderTextureNode { @@ -496,12 +496,20 @@ pub struct RenderTextureNode { executor: EditorApi, } -#[derive(Clone)] pub struct ShaderInputFrame { shader_input: Arc>, transform: DAffine2, } +impl Clone for ShaderInputFrame { + fn clone(&self) -> Self { + Self { + shader_input: self.shader_input.clone(), + transform: self.transform, + } + } +} + unsafe impl StaticType for ShaderInputFrame where E::Static: GpuExecutor, diff --git a/node-graph/graph-craft/src/proto.rs b/node-graph/graph-craft/src/proto.rs index 5fd8b4d6..bdc8c017 100644 --- a/node-graph/graph-craft/src/proto.rs +++ b/node-graph/graph-craft/src/proto.rs @@ -384,25 +384,25 @@ impl ProtoNetwork { pub fn topological_sort(&self) -> Vec { let mut sorted = Vec::new(); let inwards_edges = self.collect_inwards_edges(); - fn visit(node_id: NodeId, temp_marks: &mut HashSet, sorted: &mut Vec, inwards_edges: &HashMap>) { + fn visit(node_id: NodeId, temp_marks: &mut HashSet, sorted: &mut Vec, inwards_edges: &HashMap>, network: &ProtoNetwork) { if sorted.contains(&node_id) { return; }; if temp_marks.contains(&node_id) { - panic!("Cycle detected"); + panic!("Cycle detected {:#?}, {:#?}", &inwards_edges, &network); } if let Some(dependencies) = inwards_edges.get(&node_id) { temp_marks.insert(node_id); for &dependant in dependencies { - visit(dependant, temp_marks, sorted, inwards_edges); + visit(dependant, temp_marks, sorted, inwards_edges, network); } temp_marks.remove(&node_id); } sorted.push(node_id); } assert!(self.nodes.iter().any(|(id, _)| *id == self.output), "Output id {} does not exist", self.output); - visit(self.output, &mut HashSet::new(), &mut sorted, &inwards_edges); + visit(self.output, &mut HashSet::new(), &mut sorted, &inwards_edges, self); sorted } diff --git a/node-graph/interpreted-executor/src/node_registry.rs b/node-graph/interpreted-executor/src/node_registry.rs index 1b30df5d..c0e13f20 100644 --- a/node-graph/interpreted-executor/src/node_registry.rs +++ b/node-graph/interpreted-executor/src/node_registry.rs @@ -461,6 +461,11 @@ fn node_registry() -> HashMap, input: (), output: QuantizationChannels, params: [QuantizationChannels]), async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: Vec, params: [Vec]), async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: Arc, params: [Arc]), + #[cfg(feature = "gpu")] + async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: ShaderInputFrame, params: [ShaderInputFrame]), + #[cfg(feature = "gpu")] + async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: wgpu_executor::WgpuSurface, params: [wgpu_executor::WgpuSurface]), + async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: SurfaceFrame, params: [SurfaceFrame]), register_node!(graphene_core::structural::ConsNode<_, _>, input: Image, params: [&str]), register_node!(graphene_std::raster::ImageFrameNode<_, _>, input: Image, params: [DAffine2]), #[cfg(feature = "quantization")] diff --git a/node-graph/wgpu-executor/src/lib.rs b/node-graph/wgpu-executor/src/lib.rs index 8b07cb78..5b503ce2 100644 --- a/node-graph/wgpu-executor/src/lib.rs +++ b/node-graph/wgpu-executor/src/lib.rs @@ -32,6 +32,8 @@ impl<'a, T: ApplicationIo> From> for & } } +pub type WgpuSurface = Arc>; + #[repr(C)] #[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] struct Vertex { @@ -292,7 +294,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor { view: &view, resolve_target: None, ops: wgpu::Operations { - load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), + load: wgpu::LoadOp::Load, store: true, }, })],