From 76ecdc8f1b0cc53c60f382e69cf02f507c732db4 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Thu, 29 May 2025 13:35:35 +0200 Subject: [PATCH] Fix the 'Upload Texture' node (#2680) * Fix upload texture node * Feature gate gpu node implemenations --- .../node_graph/document_node_definitions.rs | 2 +- .../gcore/src/graphic_element/renderer.rs | 2 +- .../interpreted-executor/src/node_registry.rs | 11 ++++++--- node-graph/wgpu-executor/src/lib.rs | 24 ++++++++++++------- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs b/editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs index 7dbfaef8b..86ece1bb5 100644 --- a/editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs +++ b/editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs @@ -1781,7 +1781,7 @@ fn static_nodes() -> Vec { nodes: [ DocumentNode { inputs: vec![NodeInput::scope("editor-api")], - implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::ops::IntoNode")), + implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::ops::IntoNode<&WgpuExecutor>")), ..Default::default() }, DocumentNode { diff --git a/node-graph/gcore/src/graphic_element/renderer.rs b/node-graph/gcore/src/graphic_element/renderer.rs index 6b1f4f436..bad7ce190 100644 --- a/node-graph/gcore/src/graphic_element/renderer.rs +++ b/node-graph/gcore/src/graphic_element/renderer.rs @@ -925,7 +925,7 @@ impl GraphicElementRendered for RasterFrame { fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams) { match self { RasterFrame::ImageFrame(image) => image.render_svg(render, render_params), - RasterFrame::TextureFrame(_) => unimplemented!(), + RasterFrame::TextureFrame(_) => log::warn!("tried to render texture as an svg"), } } diff --git a/node-graph/interpreted-executor/src/node_registry.rs b/node-graph/interpreted-executor/src/node_registry.rs index 3592382fc..61f3e1d84 100644 --- a/node-graph/interpreted-executor/src/node_registry.rs +++ b/node-graph/interpreted-executor/src/node_registry.rs @@ -13,7 +13,7 @@ use graphene_core::{fn_type_fut, future}; use graphene_std::Context; use graphene_std::GraphicElement; use graphene_std::any::{ComposeTypeErased, DowncastBothNode, DynAnyNode, IntoTypeErasedNode}; -use graphene_std::application_io::ImageTexture; +use graphene_std::application_io::{ImageTexture, TextureFrameTable}; use graphene_std::wasm_application_io::*; use node_registry_macros::{async_node, into_node}; use once_cell::sync::Lazy; @@ -21,12 +21,11 @@ use std::collections::HashMap; use std::sync::Arc; #[cfg(feature = "gpu")] use wgpu_executor::ShaderInputFrame; -use wgpu_executor::{WgpuSurface, WindowHandle}; +use wgpu_executor::{WgpuExecutor, WgpuSurface, WindowHandle}; // TODO: turn into hashmap fn node_registry() -> HashMap> { let node_types: Vec<(ProtoNodeIdentifier, NodeConstructor, NodeIOTypes)> = vec![ - into_node!(from: f64, to: f64), into_node!(from: f64, to: f64), into_node!(from: u32, to: f64), into_node!(from: u8, to: u32), @@ -113,6 +112,12 @@ fn node_registry() -> HashMap, input: Context, fn_params: [Context => ShaderInputFrame]), #[cfg(feature = "gpu")] + async_node!(graphene_core::memo::ImpureMemoNode<_, _, _>, input: Context, fn_params: [Context => TextureFrameTable]), + #[cfg(feature = "gpu")] + async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => TextureFrameTable]), + #[cfg(feature = "gpu")] + into_node!(from: &WasmEditorApi, to: &WgpuExecutor), + #[cfg(feature = "gpu")] ( ProtoNodeIdentifier::new(stringify!(wgpu_executor::CreateGpuSurfaceNode<_>)), |args| { diff --git a/node-graph/wgpu-executor/src/lib.rs b/node-graph/wgpu-executor/src/lib.rs index 8356285dc..34ae432f6 100644 --- a/node-graph/wgpu-executor/src/lib.rs +++ b/node-graph/wgpu-executor/src/lib.rs @@ -8,7 +8,7 @@ pub use executor::GpuExecutor; use futures::Future; use glam::{DAffine2, UVec2}; use gpu_executor::{ComputePassDimensions, GPUConstant, StorageBufferOptions, TextureBufferOptions, TextureBufferType, ToStorageBuffer, ToUniformBuffer}; -use graphene_core::application_io::{ApplicationIo, EditorApi, ImageTexture, SurfaceHandle}; +use graphene_core::application_io::{ApplicationIo, EditorApi, ImageTexture, SurfaceHandle, TextureFrameTable}; use graphene_core::raster::image::ImageFrameTable; use graphene_core::raster::{Image, SRGBA8}; use graphene_core::transform::{Footprint, Transform}; @@ -910,14 +910,14 @@ async fn render_texture<'a: 'n>( } #[node_macro::node(category(""))] -async fn upload_texture<'a: 'n>(_: impl ExtractFootprint + Ctx, input: ImageFrameTable, executor: &'a WgpuExecutor) -> ImageTexture { +async fn upload_texture<'a: 'n>(_: impl ExtractFootprint + Ctx, input: ImageFrameTable, executor: &'a WgpuExecutor) -> TextureFrameTable { // let new_data: Vec = input.image.data.into_iter().map(|c| c.into()).collect(); - let input = input.one_instance_ref().instance; - let new_data: Vec = input.data.iter().map(|x| (*x).into()).collect(); + let image = input.one_instance_ref().instance; + let new_data: Vec = image.data.iter().map(|x| (*x).into()).collect(); let new_image = Image { - width: input.width, - height: input.height, + width: image.width, + height: image.height, data: new_data, base64_string: None, }; @@ -929,10 +929,18 @@ async fn upload_texture<'a: 'n>(_: impl ExtractFootprint + Ctx, input: ImageFram _ => unreachable!("Unsupported ShaderInput type"), }; - ImageTexture { + let texture = ImageTexture { texture: texture.into(), // TODO: Find an alternate way to encode the transform and alpha_blend now that these fields have been moved up out of ImageTexture // transform: input.transform, // alpha_blend: Default::default(), - } + }; + let mut result_table = TextureFrameTable::empty(); + result_table.push(graphene_core::instances::Instance { + instance: texture, + transform: input.transform(), + alpha_blending: *input.one_instance_ref().alpha_blending, + source_node_id: *input.one_instance_ref().source_node_id, + }); + result_table }