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:
TrueDoctor
2022-12-05 12:56:36 +01:00
committed by Keavon Chambers
parent 33d5db76c0
commit 57a1f653e1
26 changed files with 2140 additions and 620 deletions

View File

@@ -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}

View 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,
}

View File

@@ -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> {

View File

@@ -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> {

View File

@@ -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;

View File

@@ -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;