mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Implement node graph gpu execution via vulkano and rust gpu (#870)
* Add Executor abstraction * Resolve inputs for proto nodes by adding compose nodes * Add infrastructure for compiling gpu code * Integrate nodegraph gpu execution into graph-crafter * Extract graphene core path from env vars * Make Color struct usable for gpu code
This commit is contained in:
committed by
Keavon Chambers
parent
33d5db76c0
commit
57a1f653e1
@@ -10,14 +10,16 @@ license = "MIT OR Apache-2.0"
|
||||
|
||||
[features]
|
||||
std = ["dyn-any"]
|
||||
default = ["async"]
|
||||
gpu = ["spirv-std"]
|
||||
default = ["async", "serde"]
|
||||
gpu = ["spirv-std", "bytemuck"]
|
||||
async = ["async-trait"]
|
||||
nightly = []
|
||||
serde = ["dep:serde"]
|
||||
|
||||
[dependencies]
|
||||
dyn-any = {path = "../../libraries/dyn-any", features = ["derive"], optional = true}
|
||||
|
||||
spirv-std = { git = "https://github.com/EmbarkStudios/rust-gpu", features = ["glam"] , optional = true}
|
||||
bytemuck = {version = "1.8", features = ["derive"], optional = true}
|
||||
async-trait = {version = "0.1", optional = true}
|
||||
serde = {version = "1.0", features = ["derive"]}
|
||||
serde = {version = "1.0", features = ["derive"], optional = true}
|
||||
|
||||
8
node-graph/gcore/src/gpu.rs
Normal file
8
node-graph/gcore/src/gpu.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Pod, Zeroable)]
|
||||
pub struct PushConstants {
|
||||
pub n: u32,
|
||||
pub node: u32,
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
#![no_std]
|
||||
#![cfg_attr(target_arch = "spirv", feature(register_attr), register_attr(spirv))]
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
extern crate alloc;
|
||||
|
||||
@@ -11,20 +9,18 @@ use async_trait::async_trait;
|
||||
|
||||
pub mod generic;
|
||||
pub mod ops;
|
||||
pub mod raster;
|
||||
pub mod structural;
|
||||
pub mod value;
|
||||
|
||||
#[cfg(feature = "gpu")]
|
||||
pub mod gpu;
|
||||
|
||||
pub mod raster;
|
||||
|
||||
pub trait Node<T> {
|
||||
type Output;
|
||||
|
||||
fn eval(self, input: T) -> Self::Output;
|
||||
fn input(&self) -> &str {
|
||||
core::any::type_name::<T>()
|
||||
}
|
||||
fn output(&self) -> &str {
|
||||
core::any::type_name::<Self::Output>()
|
||||
}
|
||||
}
|
||||
|
||||
trait Input<I> {
|
||||
|
||||
@@ -3,7 +3,7 @@ use core::ops::Add;
|
||||
|
||||
use crate::{Node, RefNode};
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
pub struct AddNode;
|
||||
impl<'n, L: Add<R, Output = O> + 'n, R, O: 'n> Node<(L, R)> for AddNode {
|
||||
type Output = <L as Add<R>>::Output;
|
||||
@@ -30,6 +30,12 @@ impl<'n, L: Add<R, Output = O> + 'n + Copy, R: Copy, O: 'n> Node<&'n (L, R)> for
|
||||
}
|
||||
}
|
||||
|
||||
impl AddNode {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub mod dynamic {
|
||||
use super::*;
|
||||
@@ -156,7 +162,7 @@ impl<'n, T: Clone + 'n> Node<T> for DupNode {
|
||||
}
|
||||
|
||||
/// Return the Input Argument
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
pub struct IdNode;
|
||||
impl<T> Node<T> for IdNode {
|
||||
type Output = T;
|
||||
@@ -177,6 +183,12 @@ impl<T> RefNode<T> for IdNode {
|
||||
}
|
||||
}
|
||||
|
||||
impl IdNode {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MapResultNode<MN, I, E>(pub MN, pub PhantomData<(I, E)>);
|
||||
|
||||
impl<MN: Node<I>, I, E> Node<Result<I, E>> for MapResultNode<MN, I, E> {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
use crate::Node;
|
||||
|
||||
use self::color::Color;
|
||||
|
||||
pub mod color;
|
||||
use self::color::Color;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct GrayscaleColorNode;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#[cfg(feature = "std")]
|
||||
use dyn_any::{DynAny, StaticType};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Structure that represents a color.
|
||||
@@ -8,7 +9,7 @@ use serde::{Deserialize, Serialize};
|
||||
/// the values encode the brightness of each channel proportional to the light intensity in cd/m² (nits) in HDR, and `0.0` (black) to `1.0` (white) in SDR color.
|
||||
#[repr(C)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize, DynAny))]
|
||||
#[cfg_attr(not(feature = "std"), derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize))]
|
||||
#[cfg_attr(not(feature = "std"), derive(Debug, Clone, Copy, PartialEq, Default))]
|
||||
pub struct Color {
|
||||
red: f32,
|
||||
green: f32,
|
||||
@@ -35,11 +36,13 @@ impl Color {
|
||||
/// let color = Color::from_rgbaf32(1.0, 1.0, 1.0, f32::NAN);
|
||||
/// assert!(color == None);
|
||||
/// ```
|
||||
#[cfg(not(target_arch = "spirv"))]
|
||||
pub fn from_rgbaf32(red: f32, green: f32, blue: f32, alpha: f32) -> Option<Color> {
|
||||
if alpha > 1. || [red, green, blue, alpha].iter().any(|c| c.is_sign_negative() || !c.is_finite()) {
|
||||
return None;
|
||||
}
|
||||
Some(Color { red, green, blue, alpha })
|
||||
let color = Color { red, green, blue, alpha };
|
||||
Some(color)
|
||||
}
|
||||
|
||||
/// Return an opaque `Color` from given `f32` RGB channels.
|
||||
@@ -230,6 +233,7 @@ impl Color {
|
||||
/// use graphene_core::raster::color::Color;
|
||||
/// let color = Color::from_rgba_str("7C67FA61").unwrap();
|
||||
/// ```
|
||||
#[cfg(not(target_arch = "spirv"))]
|
||||
pub fn from_rgba_str(color_str: &str) -> Option<Color> {
|
||||
if color_str.len() != 8 {
|
||||
return None;
|
||||
@@ -247,6 +251,7 @@ impl Color {
|
||||
/// use graphene_core::raster::color::Color;
|
||||
/// let color = Color::from_rgb_str("7C67FA").unwrap();
|
||||
/// ```
|
||||
#[cfg(not(target_arch = "spirv"))]
|
||||
pub fn from_rgb_str(color_str: &str) -> Option<Color> {
|
||||
if color_str.len() != 6 {
|
||||
return None;
|
||||
|
||||
Reference in New Issue
Block a user