mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-30 06:18:12 +08:00
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
This commit is contained in:
committed by
Keavon Chambers
parent
45b04f4eb9
commit
5b6db0a762
Generated
+2
@@ -1872,6 +1872,7 @@ dependencies = [
|
|||||||
"env_logger",
|
"env_logger",
|
||||||
"futures",
|
"futures",
|
||||||
"glam",
|
"glam",
|
||||||
|
"gpu-executor",
|
||||||
"graph-craft",
|
"graph-craft",
|
||||||
"graphene-core",
|
"graphene-core",
|
||||||
"graphene-std",
|
"graphene-std",
|
||||||
@@ -1889,6 +1890,7 @@ dependencies = [
|
|||||||
"specta",
|
"specta",
|
||||||
"test-case",
|
"test-case",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"wgpu-executor",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
+3
-1
@@ -11,7 +11,7 @@ repository = "https://github.com/GraphiteEditor/Graphite"
|
|||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|
||||||
[features]
|
[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 = [
|
quantization = [
|
||||||
"graphene-std/quantization",
|
"graphene-std/quantization",
|
||||||
"interpreted-executor/quantization",
|
"interpreted-executor/quantization",
|
||||||
@@ -40,6 +40,8 @@ image = { version = "0.24", default-features = false, features = [
|
|||||||
"png",
|
"png",
|
||||||
] }
|
] }
|
||||||
graph-craft = { path = "../node-graph/graph-craft" }
|
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" }
|
interpreted-executor = { path = "../node-graph/interpreted-executor" }
|
||||||
dyn-any = { path = "../libraries/dyn-any" }
|
dyn-any = { path = "../libraries/dyn-any" }
|
||||||
graphene-core = { path = "../node-graph/gcore" }
|
graphene-core = { path = "../node-graph/gcore" }
|
||||||
|
|||||||
+465
-3
@@ -8,15 +8,21 @@ use graph_craft::document::value::*;
|
|||||||
use graph_craft::document::*;
|
use graph_craft::document::*;
|
||||||
use graph_craft::imaginate_input::ImaginateSamplingMethod;
|
use graph_craft::imaginate_input::ImaginateSamplingMethod;
|
||||||
use graph_craft::NodeIdentifier;
|
use graph_craft::NodeIdentifier;
|
||||||
|
#[cfg(feature = "gpu")]
|
||||||
|
use graphene_core::application_io::SurfaceHandle;
|
||||||
use graphene_core::raster::brush_cache::BrushCache;
|
use graphene_core::raster::brush_cache::BrushCache;
|
||||||
use graphene_core::raster::{BlendMode, Color, Image, ImageFrame, LuminanceCalculation, RedGreenBlue, RelativeAbsolute, SelectiveColorChoice};
|
use graphene_core::raster::{BlendMode, Color, Image, ImageFrame, LuminanceCalculation, RedGreenBlue, RelativeAbsolute, SelectiveColorChoice};
|
||||||
use graphene_core::text::Font;
|
use graphene_core::text::Font;
|
||||||
use graphene_core::vector::VectorData;
|
use graphene_core::vector::VectorData;
|
||||||
use graphene_core::*;
|
use graphene_core::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "gpu")]
|
||||||
|
use gpu_executor::*;
|
||||||
use graphene_std::wasm_application_io::WasmEditorApi;
|
use graphene_std::wasm_application_io::WasmEditorApi;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
#[cfg(feature = "gpu")]
|
||||||
|
use wgpu_executor::WgpuExecutor;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||||
pub struct DocumentInputType {
|
pub struct DocumentInputType {
|
||||||
@@ -743,8 +749,8 @@ fn static_nodes() -> Vec<DocumentNodeType> {
|
|||||||
},
|
},
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
name: "Create Uniform".to_string(),
|
name: "Create Uniform".to_string(),
|
||||||
inputs: vec![NodeInput::Network(concrete!(f32))],
|
inputs: vec![NodeInput::Network(generic!(T)), NodeInput::node(0, 0)],
|
||||||
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu-executor::UniformNode<_>")),
|
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("gpu_executor::UniformNode<_>")),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
@@ -776,9 +782,466 @@ fn static_nodes() -> Vec<DocumentNodeType> {
|
|||||||
name: "Uniform",
|
name: "Uniform",
|
||||||
data_type: FrontendGraphDataType::General,
|
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<u8>)), 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,
|
properties: node_properties::input_properties,
|
||||||
},
|
},
|
||||||
#[cfg(feature = "gpu")]
|
#[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<WgpuExecutor>)),
|
||||||
|
NodeInput::node(0, 0),
|
||||||
|
NodeInput::Network(concrete!(ShaderInput<WgpuExecutor>)),
|
||||||
|
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<WgpuExecutor>)),
|
||||||
|
},
|
||||||
|
DocumentInputType {
|
||||||
|
name: "In",
|
||||||
|
data_type: FrontendGraphDataType::General,
|
||||||
|
default: NodeInput::Network(concrete!(WasmEditorApi)),
|
||||||
|
},
|
||||||
|
DocumentInputType {
|
||||||
|
name: "In",
|
||||||
|
data_type: FrontendGraphDataType::General,
|
||||||
|
default: NodeInput::Network(concrete!(ShaderInput<WgpuExecutor>)),
|
||||||
|
},
|
||||||
|
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!(<WgpuExecutor as GpuExecutor>::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<WgpuExecutor>)),
|
||||||
|
},
|
||||||
|
DocumentInputType {
|
||||||
|
name: "ArcShaderInput",
|
||||||
|
data_type: FrontendGraphDataType::General,
|
||||||
|
default: NodeInput::Network(concrete!(Arc<ShaderInput<WgpuExecutor>>)),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
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!(<WgpuExecutor as GpuExecutor>::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<ShaderInput<WgpuExecutor>>)), 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<WgpuExecutor>)),
|
||||||
|
NodeInput::Network(concrete!(Arc<SurfaceHandle<<WgpuExecutor as GpuExecutor>::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<Color>)), 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 {
|
DocumentNodeType {
|
||||||
name: "GpuImage",
|
name: "GpuImage",
|
||||||
category: "Image Adjustments",
|
category: "Image Adjustments",
|
||||||
@@ -826,7 +1289,6 @@ fn static_nodes() -> Vec<DocumentNodeType> {
|
|||||||
properties: node_properties::no_properties,
|
properties: node_properties::no_properties,
|
||||||
},
|
},
|
||||||
#[cfg(feature = "quantization")]
|
#[cfg(feature = "quantization")]
|
||||||
#[cfg(feature = "quantization")]
|
|
||||||
DocumentNodeType {
|
DocumentNodeType {
|
||||||
name: "Generate Quantization",
|
name: "Generate Quantization",
|
||||||
category: "Quantization",
|
category: "Quantization",
|
||||||
|
|||||||
@@ -485,10 +485,10 @@ async fn read_output_buffer_node<'a: 'input, E: 'a + GpuExecutor>(buffer: Arc<Sh
|
|||||||
pub struct CreateGpuSurfaceNode {}
|
pub struct CreateGpuSurfaceNode {}
|
||||||
|
|
||||||
#[node_macro::node_fn(CreateGpuSurfaceNode)]
|
#[node_macro::node_fn(CreateGpuSurfaceNode)]
|
||||||
async fn create_gpu_surface<'a: 'input, E: 'a + GpuExecutor<Window = Io::Surface>, Io: ApplicationIo<Executor = E>>(editor_api: EditorApi<'a, Io>) -> SurfaceHandle<E::Surface> {
|
async fn create_gpu_surface<'a: 'input, E: 'a + GpuExecutor<Window = Io::Surface>, Io: ApplicationIo<Executor = E>>(editor_api: EditorApi<'a, Io>) -> Arc<SurfaceHandle<E::Surface>> {
|
||||||
let canvas = editor_api.application_io.create_surface();
|
let canvas = editor_api.application_io.create_surface();
|
||||||
let executor = editor_api.application_io.gpu_executor().unwrap();
|
let executor = editor_api.application_io.gpu_executor().unwrap();
|
||||||
executor.create_surface(canvas).unwrap()
|
Arc::new(executor.create_surface(canvas).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RenderTextureNode<Surface, EditorApi> {
|
pub struct RenderTextureNode<Surface, EditorApi> {
|
||||||
@@ -496,12 +496,20 @@ pub struct RenderTextureNode<Surface, EditorApi> {
|
|||||||
executor: EditorApi,
|
executor: EditorApi,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct ShaderInputFrame<E: GpuExecutor + ?Sized> {
|
pub struct ShaderInputFrame<E: GpuExecutor + ?Sized> {
|
||||||
shader_input: Arc<ShaderInput<E>>,
|
shader_input: Arc<ShaderInput<E>>,
|
||||||
transform: DAffine2,
|
transform: DAffine2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E: GpuExecutor + ?Sized> Clone for ShaderInputFrame<E> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
shader_input: self.shader_input.clone(),
|
||||||
|
transform: self.transform,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe impl<E: GpuExecutor + ?Sized + StaticType> StaticType for ShaderInputFrame<E>
|
unsafe impl<E: GpuExecutor + ?Sized + StaticType> StaticType for ShaderInputFrame<E>
|
||||||
where
|
where
|
||||||
E::Static: GpuExecutor,
|
E::Static: GpuExecutor,
|
||||||
|
|||||||
@@ -384,25 +384,25 @@ impl ProtoNetwork {
|
|||||||
pub fn topological_sort(&self) -> Vec<NodeId> {
|
pub fn topological_sort(&self) -> Vec<NodeId> {
|
||||||
let mut sorted = Vec::new();
|
let mut sorted = Vec::new();
|
||||||
let inwards_edges = self.collect_inwards_edges();
|
let inwards_edges = self.collect_inwards_edges();
|
||||||
fn visit(node_id: NodeId, temp_marks: &mut HashSet<NodeId>, sorted: &mut Vec<NodeId>, inwards_edges: &HashMap<NodeId, Vec<NodeId>>) {
|
fn visit(node_id: NodeId, temp_marks: &mut HashSet<NodeId>, sorted: &mut Vec<NodeId>, inwards_edges: &HashMap<NodeId, Vec<NodeId>>, network: &ProtoNetwork) {
|
||||||
if sorted.contains(&node_id) {
|
if sorted.contains(&node_id) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if temp_marks.contains(&node_id) {
|
if temp_marks.contains(&node_id) {
|
||||||
panic!("Cycle detected");
|
panic!("Cycle detected {:#?}, {:#?}", &inwards_edges, &network);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(dependencies) = inwards_edges.get(&node_id) {
|
if let Some(dependencies) = inwards_edges.get(&node_id) {
|
||||||
temp_marks.insert(node_id);
|
temp_marks.insert(node_id);
|
||||||
for &dependant in dependencies {
|
for &dependant in dependencies {
|
||||||
visit(dependant, temp_marks, sorted, inwards_edges);
|
visit(dependant, temp_marks, sorted, inwards_edges, network);
|
||||||
}
|
}
|
||||||
temp_marks.remove(&node_id);
|
temp_marks.remove(&node_id);
|
||||||
}
|
}
|
||||||
sorted.push(node_id);
|
sorted.push(node_id);
|
||||||
}
|
}
|
||||||
assert!(self.nodes.iter().any(|(id, _)| *id == self.output), "Output id {} does not exist", self.output);
|
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
|
sorted
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -461,6 +461,11 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||||||
async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: QuantizationChannels, params: [QuantizationChannels]),
|
async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: QuantizationChannels, params: [QuantizationChannels]),
|
||||||
async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: Vec<DVec2>, params: [Vec<DVec2>]),
|
async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: Vec<DVec2>, params: [Vec<DVec2>]),
|
||||||
async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: Arc<WasmSurfaceHandle>, params: [Arc<WasmSurfaceHandle>]),
|
async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: Arc<WasmSurfaceHandle>, params: [Arc<WasmSurfaceHandle>]),
|
||||||
|
#[cfg(feature = "gpu")]
|
||||||
|
async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: ShaderInputFrame<WgpuExecutor>, params: [ShaderInputFrame<WgpuExecutor>]),
|
||||||
|
#[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<Color>, params: [&str]),
|
register_node!(graphene_core::structural::ConsNode<_, _>, input: Image<Color>, params: [&str]),
|
||||||
register_node!(graphene_std::raster::ImageFrameNode<_, _>, input: Image<Color>, params: [DAffine2]),
|
register_node!(graphene_std::raster::ImageFrameNode<_, _>, input: Image<Color>, params: [DAffine2]),
|
||||||
#[cfg(feature = "quantization")]
|
#[cfg(feature = "quantization")]
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ impl<'a, T: ApplicationIo<Executor = WgpuExecutor>> From<EditorApi<'a, T>> for &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type WgpuSurface = Arc<SurfaceHandle<wgpu::Surface>>;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
@@ -292,7 +294,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
|||||||
view: &view,
|
view: &view,
|
||||||
resolve_target: None,
|
resolve_target: None,
|
||||||
ops: wgpu::Operations {
|
ops: wgpu::Operations {
|
||||||
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
|
load: wgpu::LoadOp::Load,
|
||||||
store: true,
|
store: true,
|
||||||
},
|
},
|
||||||
})],
|
})],
|
||||||
|
|||||||
Reference in New Issue
Block a user