mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-30 04:28:11 +08:00
ICE
This commit is contained in:
committed by
Keavon Chambers
parent
edb33e0c82
commit
1e52715d95
@@ -43,7 +43,7 @@ async fn post_compile_spirv(State(state): State<Arc<AppState>>, Json(compile_req
|
|||||||
let result = compile_request.compile(state.compile_dir.path().to_str().expect("non utf8 tempdir path"), &path).map_err(|e| {
|
let result = compile_request.compile(state.compile_dir.path().to_str().expect("non utf8 tempdir path"), &path).map_err(|e| {
|
||||||
eprintln!("compilation failed: {}", e);
|
eprintln!("compilation failed: {}", e);
|
||||||
StatusCode::INTERNAL_SERVER_ERROR
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
});
|
})?;
|
||||||
state.cache.write().unwrap().insert(compile_request, result.clone());
|
state.cache.write().unwrap().insert(compile_request, Ok(result.clone()));
|
||||||
result
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,17 @@ impl<T: Fn(I) -> O, I, O> FnNode<T, I, O> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct FnOnceNode<T: FnMut(I) -> O, I, O: Default>(T, PhantomData<(I, O)>);
|
||||||
|
|
||||||
|
impl<'i, T: FnMut(I) -> O + 'i, I: 'i, O: 'i + Default> FnOnceNode<T, I, O> {
|
||||||
|
pub fn new(f: T) -> Self {
|
||||||
|
FnOnceNode(f, PhantomData)
|
||||||
|
}
|
||||||
|
fn eval(&'i mut self, input: I) -> O {
|
||||||
|
self.0(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct FnNodeWithState<'i, T: Fn(I, &'i State) -> O, I, O, State: 'i>(T, State, PhantomData<(&'i O, I)>);
|
pub struct FnNodeWithState<'i, T: Fn(I, &'i State) -> O, I, O, State: 'i>(T, State, PhantomData<(&'i O, I)>);
|
||||||
impl<'i, I: 'i, O: 'i, State, T: Fn(I, &'i State) -> O + 'i> Node<'i, I> for FnNodeWithState<'i, T, I, O, State> {
|
impl<'i, I: 'i, O: 'i, State, T: Fn(I, &'i State) -> O + 'i> Node<'i, I> for FnNodeWithState<'i, T, I, O, State> {
|
||||||
type Output = O;
|
type Output = O;
|
||||||
|
|||||||
+42
-28
@@ -44,7 +44,7 @@ use core::any::TypeId;
|
|||||||
pub use raster::Color;
|
pub use raster::Color;
|
||||||
|
|
||||||
// pub trait Node: for<'n> NodeIO<'n> {
|
// pub trait Node: for<'n> NodeIO<'n> {
|
||||||
pub trait Node<'i, Input: 'i>: 'i {
|
pub trait Node<'i, Input: 'i>: 'i + NodeMut<'i, Input, MutOutput = Self::Output> {
|
||||||
type Output: 'i;
|
type Output: 'i;
|
||||||
fn eval(&'i self, input: Input) -> Self::Output;
|
fn eval(&'i self, input: Input) -> Self::Output;
|
||||||
fn reset(&self) {}
|
fn reset(&self) {}
|
||||||
@@ -55,6 +55,32 @@ pub trait Node<'i, Input: 'i>: 'i {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait NodeMut<'i, Input: 'i>: 'i {
|
||||||
|
type MutOutput: 'i;
|
||||||
|
fn eval_mut(&'i mut self, input: Input) -> Self::MutOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait NodeOnce<'i, Input>
|
||||||
|
where
|
||||||
|
Input: 'i,
|
||||||
|
{
|
||||||
|
type OnceOutput: 'i;
|
||||||
|
fn eval_once(self, input: Input) -> Self::OnceOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'i, T: Node<'i, I>, I: 'i> NodeOnce<'i, I> for &'i T {
|
||||||
|
type OnceOutput = T::Output;
|
||||||
|
fn eval_once(self, input: I) -> Self::OnceOutput {
|
||||||
|
(self).eval(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'i, T: Node<'i, I> + ?Sized, I: 'i> NodeMut<'i, I> for T {
|
||||||
|
type MutOutput = T::Output;
|
||||||
|
fn eval_mut(&'i mut self, input: I) -> Self::MutOutput {
|
||||||
|
(*self).eval(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
mod types;
|
mod types;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
@@ -98,52 +124,40 @@ where
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'i, 's: 'i, I: 'i, O: 'i, N: Node<'i, I, Output = O>> Node<'i, I> for &'s N {
|
impl<'i, 's: 'i, I: 'i, N: Node<'i, I> + ?Sized> Node<'i, I> for &'i N {
|
||||||
|
type Output = N::Output;
|
||||||
|
fn eval(&'i self, input: I) -> N::Output {
|
||||||
|
(*self).eval(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
impl<'i, 's: 'i, I: 'i, O: 'i, N: Node<'i, I, Output = O> + ?Sized> Node<'i, I> for Box<N> {
|
||||||
type Output = O;
|
type Output = O;
|
||||||
|
fn eval(&'i self, input: I) -> O {
|
||||||
fn eval(&'i self, input: I) -> Self::Output {
|
|
||||||
(**self).eval(input)
|
(**self).eval(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
impl<'i, 's: 'i, I: 'i, O: 'i, N: Node<'i, I, Output = O>> Node<'i, I> for Box<N> {
|
impl<'i, 's: 'i, I: 'i, O: 'i, N: Node<'i, I, Output = O> + ?Sized> Node<'i, I> for alloc::sync::Arc<N> {
|
||||||
type Output = O;
|
type Output = O;
|
||||||
|
fn eval(&'i self, input: I) -> O {
|
||||||
fn eval(&'i self, input: I) -> Self::Output {
|
|
||||||
(**self).eval(input)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
impl<'i, 's: 'i, I: 'i, O: 'i, N: Node<'i, I, Output = O>> Node<'i, I> for alloc::sync::Arc<N> {
|
|
||||||
type Output = O;
|
|
||||||
|
|
||||||
fn eval(&'i self, input: I) -> Self::Output {
|
|
||||||
(**self).eval(input)
|
(**self).eval(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'i, I: 'i, O: 'i> Node<'i, I> for &'i dyn Node<'i, I, Output = O> {
|
|
||||||
type Output = O;
|
|
||||||
|
|
||||||
fn eval(&'i self, input: I) -> Self::Output {
|
|
||||||
(**self).eval(input)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
|
|
||||||
use dyn_any::StaticTypeSized;
|
use dyn_any::StaticTypeSized;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
impl<'i, I: 'i, O: 'i> Node<'i, I> for Pin<Box<dyn Node<'i, I, Output = O> + 'i>> {
|
impl<'i, I: 'i, O: 'i> Node<'i, I> for Pin<Box<dyn Node<'i, I, Output = O, MutOutput = O> + 'i>> {
|
||||||
type Output = O;
|
type Output = O;
|
||||||
|
fn eval(&'i self, input: I) -> O {
|
||||||
fn eval(&'i self, input: I) -> Self::Output {
|
|
||||||
(**self).eval(input)
|
(**self).eval(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'i, I: 'i, O: 'i> Node<'i, I> for Pin<&'i (dyn NodeIO<'i, I, Output = O> + 'i)> {
|
impl<'i, I: 'i, O: 'i> Node<'i, I> for Pin<&'i (dyn NodeIO<'i, I, Output = O, MutOutput = O> + 'i)> {
|
||||||
type Output = O;
|
type Output = O;
|
||||||
|
fn eval(&'i self, input: I) -> O {
|
||||||
fn eval(&'i self, input: I) -> Self::Output {
|
|
||||||
(**self).eval(input)
|
(**self).eval(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ where
|
|||||||
// TODO: This should return a reference to the cached cached_value
|
// TODO: This should return a reference to the cached cached_value
|
||||||
// but that requires a lot of lifetime magic <- This was suggested by copilot but is pretty acurate xD
|
// but that requires a lot of lifetime magic <- This was suggested by copilot but is pretty acurate xD
|
||||||
type Output = Pin<Box<dyn Future<Output = T> + 'i>>;
|
type Output = Pin<Box<dyn Future<Output = T> + 'i>>;
|
||||||
fn eval(&'i self, input: ()) -> Self::Output {
|
fn eval(&'i self, input: ()) -> Pin<Box<dyn Future<Output = T> + 'i>> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if let Some(cached_value) = self.cache.take() {
|
if let Some(cached_value) = self.cache.take() {
|
||||||
self.cache.set(Some(cached_value.clone()));
|
self.cache.set(Some(cached_value.clone()));
|
||||||
|
|||||||
@@ -1,58 +1,69 @@
|
|||||||
use crate::raster::Color;
|
use crate::raster::Color;
|
||||||
use crate::Node;
|
use crate::Node;
|
||||||
|
use bytemuck::{Pod, Zeroable};
|
||||||
use dyn_any::{DynAny, StaticType};
|
use dyn_any::{DynAny, StaticType};
|
||||||
|
|
||||||
#[cfg(target_arch = "spirv")]
|
#[cfg(target_arch = "spirv")]
|
||||||
use spirv_std::num_traits::Float;
|
use spirv_std::num_traits::Float;
|
||||||
|
|
||||||
#[derive(Clone, Debug, DynAny, PartialEq)]
|
#[derive(Clone, Copy, Debug, DynAny, PartialEq, Pod, Zeroable)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
|
#[repr(C)]
|
||||||
pub struct Quantization {
|
pub struct Quantization {
|
||||||
pub fn_index: usize,
|
|
||||||
pub a: f32,
|
pub a: f32,
|
||||||
pub b: f32,
|
pub b_and_bits: u32,
|
||||||
pub c: f32,
|
}
|
||||||
pub d: f32,
|
|
||||||
|
impl Quantization {
|
||||||
|
pub fn a(&self) -> f32 {
|
||||||
|
self.a
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn b(&self) -> i32 {
|
||||||
|
(self.b_and_bits >> 16) as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bits(&self) -> u32 {
|
||||||
|
self.b_and_bits & 0xFF
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::hash::Hash for Quantization {
|
impl core::hash::Hash for Quantization {
|
||||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||||
self.fn_index.hash(state);
|
self.bits().hash(state);
|
||||||
self.a.to_bits().hash(state);
|
self.a().to_bits().hash(state);
|
||||||
self.b.to_bits().hash(state);
|
self.b().hash(state);
|
||||||
self.c.to_bits().hash(state);
|
|
||||||
self.d.to_bits().hash(state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Quantization {
|
impl Default for Quantization {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self { a: 1., b_and_bits: 8 }
|
||||||
fn_index: Default::default(),
|
|
||||||
a: 1.,
|
|
||||||
b: Default::default(),
|
|
||||||
c: Default::default(),
|
|
||||||
d: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type QuantizationChannels = [Quantization; 4];
|
pub type QuantizationChannels = [Quantization; 4];
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(DynAny, Clone, Copy, Debug, PartialEq, Eq, Pod, Zeroable)]
|
||||||
|
pub struct PackedPixel(u32);
|
||||||
|
|
||||||
fn quantize(value: f32, quantization: &Quantization) -> f32 {
|
#[inline(always)]
|
||||||
let Quantization { fn_index, a, b, c, d } = quantization;
|
fn quantize(value: f32, offset: u32, quantization: &Quantization) -> u32 {
|
||||||
match fn_index {
|
let a = quantization.a();
|
||||||
1 => ((value + a) * d).abs().ln() * b + c,
|
let bits = quantization.bits();
|
||||||
_ => a * value + b,
|
let b = quantization.b();
|
||||||
}
|
let value = (((a * value) * (1 << bits) as f32) as i32 + b as i32) as u32;
|
||||||
|
value << (32 - bits - offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(value: f32, quantization: &Quantization) -> f32 {
|
#[inline(always)]
|
||||||
let Quantization { fn_index, a, b, c, d } = quantization;
|
fn decode(value: u32, offset: u32, quantization: &Quantization) -> f32 {
|
||||||
match fn_index {
|
let a = quantization.a();
|
||||||
1 => -(-c / b).exp() * (a * d * (c / b).exp() - (value / b).exp()) / d,
|
let bits = quantization.bits();
|
||||||
_ => (value - b) / a,
|
let b = quantization.b();
|
||||||
}
|
let value = (value << offset) >> (32 - bits);
|
||||||
|
let value = value as i32 - b;
|
||||||
|
(value as f32 / (1 << bits) as f32) / a
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct QuantizeNode<Quantization> {
|
pub struct QuantizeNode<Quantization> {
|
||||||
@@ -60,14 +71,18 @@ pub struct QuantizeNode<Quantization> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[node_macro::node_fn(QuantizeNode)]
|
#[node_macro::node_fn(QuantizeNode)]
|
||||||
fn quantize_fn<'a>(color: Color, quantization: [Quantization; 4]) -> Color {
|
fn quantize_fn<'a>(color: Color, quantization: [Quantization; 4]) -> PackedPixel {
|
||||||
let quant = quantization.as_slice();
|
let quant = quantization;
|
||||||
let r = quantize(color.r(), &quant[0]);
|
let mut offset = 0;
|
||||||
let g = quantize(color.g(), &quant[1]);
|
let r = quantize(color.r(), offset, &quant[0]);
|
||||||
let b = quantize(color.b(), &quant[2]);
|
offset += quant[0].bits();
|
||||||
let a = quantize(color.a(), &quant[3]);
|
let g = quantize(color.g(), offset, &quant[1]);
|
||||||
|
offset += quant[1].bits();
|
||||||
|
let b = quantize(color.b(), offset, &quant[2]);
|
||||||
|
offset += quant[2].bits();
|
||||||
|
let a = quantize(color.a(), offset, &quant[3]);
|
||||||
|
|
||||||
Color::from_rgbaf32_unchecked(r, g, b, a)
|
PackedPixel(r | g | b | a)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DeQuantizeNode<Quantization> {
|
pub struct DeQuantizeNode<Quantization> {
|
||||||
@@ -75,12 +90,16 @@ pub struct DeQuantizeNode<Quantization> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[node_macro::node_fn(DeQuantizeNode)]
|
#[node_macro::node_fn(DeQuantizeNode)]
|
||||||
fn dequantize_fn<'a>(color: Color, quantization: [Quantization; 4]) -> Color {
|
fn dequantize_fn<'a>(color: PackedPixel, quantization: [Quantization; 4]) -> Color {
|
||||||
let quant = quantization.as_slice();
|
let quant = quantization;
|
||||||
let r = decode(color.r(), &quant[0]);
|
let mut offset = 0;
|
||||||
let g = decode(color.g(), &quant[1]);
|
let r = decode(color.0, offset, &quant[0]);
|
||||||
let b = decode(color.b(), &quant[2]);
|
offset += quant[0].bits();
|
||||||
let a = decode(color.a(), &quant[3]);
|
let g = decode(color.0, offset, &quant[1]);
|
||||||
|
offset += quant[1].bits();
|
||||||
|
let b = decode(color.0, offset, &quant[2]);
|
||||||
|
offset += quant[2].bits();
|
||||||
|
let a = decode(color.0, offset, &quant[3]);
|
||||||
|
|
||||||
Color::from_rgbaf32_unchecked(r, g, b, a)
|
Color::from_rgbaf32_unchecked(r, g, b, a)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use core::marker::PhantomData;
|
|||||||
|
|
||||||
use crate::Node;
|
use crate::Node;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct ComposeNode<First, Second, I> {
|
pub struct ComposeNode<First, Second, I> {
|
||||||
first: First,
|
first: First,
|
||||||
second: Second,
|
second: Second,
|
||||||
|
|||||||
@@ -216,10 +216,10 @@ pub fn compile(dir: &Path) -> Result<spirv_builder::CompileResult, spirv_builder
|
|||||||
.release(true)
|
.release(true)
|
||||||
.spirv_metadata(SpirvMetadata::Full)
|
.spirv_metadata(SpirvMetadata::Full)
|
||||||
.capability(spirv_builder::Capability::Float64)
|
.capability(spirv_builder::Capability::Float64)
|
||||||
//.extra_arg("no-early-report-zombies")
|
//.capability(spirv_builder::Capability::VariablePointersStorageBuffer)
|
||||||
//.extra_arg("no-infer-storage-classes")
|
.extra_arg("no-early-report-zombies")
|
||||||
//.extra_arg("spirt-passes=qptr,reduce")
|
.extra_arg("no-infer-storage-classes")
|
||||||
.extra_arg("spirt-passes=reduce")
|
.extra_arg("spirt-passes=qptr")
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
|||||||
@@ -23,13 +23,11 @@ extern crate spirv_std;
|
|||||||
use graphene_core::raster::adjustments::{BlendMode, BlendNode};
|
use graphene_core::raster::adjustments::{BlendMode, BlendNode};
|
||||||
use graphene_core::Color;
|
use graphene_core::Color;
|
||||||
|
|
||||||
/*
|
|
||||||
{% for input in input_nodes %}
|
{% for input in input_nodes %}
|
||||||
let i{{input.index}} = graphene_core::value::CopiedNode::new(i{{input.index}});
|
let _i{{input.index}} = graphene_core::value::CopiedNode::new(i{{input.index}});
|
||||||
let _{{input.id}} = {{input.fqn}}::new({% for arg in input.args %}{{arg}}, {% endfor %});
|
let _{{input.id}} = {{input.fqn}}::new({% for arg in input.args %}{{arg}}, {% endfor %});
|
||||||
let {{input.id}} = graphene_core::structural::ComposeNode::new(i{{input.index}}, _{{input.id}});
|
let {{input.id}} = graphene_core::structural::ComposeNode::new(_i{{input.index}}, _{{input.id}});
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
*/
|
|
||||||
|
|
||||||
{% for node in nodes %}
|
{% for node in nodes %}
|
||||||
let {{node.id}} = {{node.fqn}}::new({% for arg in node.args %}{{arg}}, {% endfor %});
|
let {{node.id}} = {{node.fqn}}::new({% for arg in node.args %}{{arg}}, {% endfor %});
|
||||||
@@ -37,7 +35,7 @@ extern crate spirv_std;
|
|||||||
|
|
||||||
{% for output in output_nodes %}
|
{% for output in output_nodes %}
|
||||||
let v = {{output}}.eval(());
|
let v = {{output}}.eval(());
|
||||||
o{{loop.index0}}[(_global_index.y * i0 + _global_index.x) as usize] = v;
|
//o{{loop.index0}}[(_global_index.y * i1 + _global_index.x) as usize] = v;
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
// TODO: Write output to buffer
|
// TODO: Write output to buffer
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ pub type DynFuture<'n, T> = Pin<Box<dyn core::future::Future<Output = T> + 'n>>;
|
|||||||
pub type LocalFuture<'n, T> = Pin<Box<dyn core::future::Future<Output = T> + 'n>>;
|
pub type LocalFuture<'n, T> = Pin<Box<dyn core::future::Future<Output = T> + 'n>>;
|
||||||
pub type Any<'n> = Box<dyn DynAny<'n> + 'n>;
|
pub type Any<'n> = Box<dyn DynAny<'n> + 'n>;
|
||||||
pub type FutureAny<'n> = DynFuture<'n, Any<'n>>;
|
pub type FutureAny<'n> = DynFuture<'n, Any<'n>>;
|
||||||
pub type TypeErasedNode<'n> = dyn for<'i> NodeIO<'i, Any<'i>, Output = FutureAny<'i>> + 'n;
|
pub type TypeErasedNode<'n> = dyn for<'i> NodeIO<'i, Any<'i>, Output = FutureAny<'i>, MutOutput = FutureAny<'i>> + 'n;
|
||||||
pub type TypeErasedPinnedRef<'n> = Pin<&'n (dyn for<'i> NodeIO<'i, Any<'i>, Output = FutureAny<'i>> + 'n)>;
|
pub type TypeErasedPinnedRef<'n> = Pin<&'n TypeErasedNode<'n>>;
|
||||||
pub type TypeErasedRef<'n> = &'n (dyn for<'i> NodeIO<'i, Any<'i>, Output = FutureAny<'i>> + 'n);
|
pub type TypeErasedRef<'n> = &'n TypeErasedNode<'n>;
|
||||||
pub type TypeErasedBox<'n> = Box<dyn for<'i> NodeIO<'i, Any<'i>, Output = FutureAny<'i>> + 'n>;
|
pub type TypeErasedBox<'n> = Box<TypeErasedNode<'n>>;
|
||||||
pub type TypeErasedPinned<'n> = Pin<Box<dyn for<'i> NodeIO<'i, Any<'i>, Output = FutureAny<'i>> + 'n>>;
|
pub type TypeErasedPinned<'n> = Pin<Box<TypeErasedNode<'n>>>;
|
||||||
|
|
||||||
pub type NodeConstructor = for<'a> fn(Vec<Arc<NodeContainer>>) -> DynFuture<'static, TypeErasedBox<'static>>;
|
pub type NodeConstructor = for<'a> fn(Vec<Arc<NodeContainer>>) -> DynFuture<'static, TypeErasedBox<'static>>;
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
let device = application_io.gpu_executor().unwrap().context.device.clone();
|
let device = application_io.gpu_executor().unwrap().context.device.clone();
|
||||||
std::thread::spawn(move || loop {
|
std::thread::spawn(move || loop {
|
||||||
std::thread::sleep(std::time::Duration::from_nanos(1));
|
std::thread::sleep(std::time::Duration::from_nanos(10));
|
||||||
device.poll(wgpu::Maintain::Poll);
|
device.poll(wgpu::Maintain::Poll);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use gpu_executor::{GpuExecutor, ShaderIO, ShaderInput};
|
|||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::*;
|
use graph_craft::document::*;
|
||||||
use graph_craft::proto::*;
|
use graph_craft::proto::*;
|
||||||
|
use graphene_core::quantization::{PackedPixel, QuantizationChannels};
|
||||||
use graphene_core::raster::*;
|
use graphene_core::raster::*;
|
||||||
use graphene_core::*;
|
use graphene_core::*;
|
||||||
use wgpu_executor::WgpuExecutor;
|
use wgpu_executor::WgpuExecutor;
|
||||||
@@ -112,15 +113,27 @@ async fn create_compute_pass_descriptor(node: DocumentNode, image: &ImageFrame<C
|
|||||||
|
|
||||||
log::debug!("inner_network: {:?}", inner_network);
|
log::debug!("inner_network: {:?}", inner_network);
|
||||||
let network = NodeNetwork {
|
let network = NodeNetwork {
|
||||||
inputs: vec![], //vec![0, 1],
|
inputs: vec![1, 2], //vec![0, 1],
|
||||||
outputs: vec![NodeOutput::new(1, 0)],
|
outputs: vec![NodeOutput::new(6, 0)],
|
||||||
nodes: [
|
nodes: [
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
name: "Slice".into(),
|
name: "Slice".into(),
|
||||||
inputs: vec![NodeInput::Inline(InlineRust::new("i1[(_global_index.y * i0 + _global_index.x) as usize]".into(), concrete![Color]))],
|
inputs: vec![NodeInput::Inline(InlineRust::new("i2[(_global_index.y * i1 + _global_index.x) as usize]".into(), concrete![Color]))],
|
||||||
implementation: DocumentNodeImplementation::Unresolved("graphene_core::value::CopiedNode".into()),
|
implementation: DocumentNodeImplementation::Unresolved("graphene_core::value::CopiedNode".into()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
DocumentNode {
|
||||||
|
name: "Quantization".into(),
|
||||||
|
inputs: vec![NodeInput::Network(concrete!(quantization::Quantization))],
|
||||||
|
implementation: DocumentNodeImplementation::Unresolved("graphene_core::ops::CloneNode".into()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
DocumentNode {
|
||||||
|
name: "Width".into(),
|
||||||
|
inputs: vec![NodeInput::Network(concrete!(u32))],
|
||||||
|
implementation: DocumentNodeImplementation::Unresolved("graphene_core::ops::IdNode".into()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
/*DocumentNode {
|
/*DocumentNode {
|
||||||
name: "Index".into(),
|
name: "Index".into(),
|
||||||
//inputs: vec![NodeInput::Network(concrete!(UVec3))],
|
//inputs: vec![NodeInput::Network(concrete!(UVec3))],
|
||||||
@@ -135,26 +148,36 @@ async fn create_compute_pass_descriptor(node: DocumentNode, image: &ImageFrame<C
|
|||||||
implementation: DocumentNodeImplementation::Unresolved("graphene_core::storage::GetNode".into()),
|
implementation: DocumentNodeImplementation::Unresolved("graphene_core::storage::GetNode".into()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},*/
|
},*/
|
||||||
|
DocumentNode {
|
||||||
|
name: "Dequantize".into(),
|
||||||
|
inputs: vec![NodeInput::node(0, 0), NodeInput::node(1, 0)],
|
||||||
|
implementation: DocumentNodeImplementation::proto("graphene_core::quantization::DeQuantizeNode"),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
name: "MapNode".into(),
|
name: "MapNode".into(),
|
||||||
inputs: vec![NodeInput::node(0, 0)],
|
inputs: vec![NodeInput::node(3, 0)],
|
||||||
implementation: DocumentNodeImplementation::Network(inner_network),
|
implementation: DocumentNodeImplementation::Network(inner_network),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
/*
|
DocumentNode {
|
||||||
|
name: "Quantize".into(),
|
||||||
|
inputs: vec![NodeInput::node(4, 0), NodeInput::node(1, 0)],
|
||||||
|
implementation: DocumentNodeImplementation::proto("graphene_core::quantization::QuantizeNode"),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
name: "SaveNode".into(),
|
name: "SaveNode".into(),
|
||||||
inputs: vec![
|
inputs: vec![
|
||||||
//NodeInput::node(0, 0),
|
NodeInput::node(5, 0),
|
||||||
NodeInput::Inline(InlineRust::new(
|
NodeInput::Inline(InlineRust::new(
|
||||||
"o0[_global_index.x as usize] = i0[_global_index.x as usize]".into(),
|
"move |x| o0[(_global_index.y * i1 + _global_index.x) as usize] = x".into(),
|
||||||
Type::Fn(Box::new(concrete!(Color)), Box::new(concrete!(()))),
|
Type::Fn(Box::new(concrete!(Color)), Box::new(concrete!(()))),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
implementation: DocumentNodeImplementation::Unresolved("graphene_core::value::ValueNode".into()),
|
implementation: DocumentNodeImplementation::Unresolved("graphene_core::generic::FnOnceNode".into()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
*/
|
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
@@ -171,12 +194,13 @@ async fn create_compute_pass_descriptor(node: DocumentNode, image: &ImageFrame<C
|
|||||||
vec![concrete!(Color)],
|
vec![concrete!(Color)],
|
||||||
ShaderIO {
|
ShaderIO {
|
||||||
inputs: vec![
|
inputs: vec![
|
||||||
|
ShaderInput::UniformBuffer((), concrete!(quantization::QuantizationChannels)),
|
||||||
ShaderInput::UniformBuffer((), concrete!(u32)),
|
ShaderInput::UniformBuffer((), concrete!(u32)),
|
||||||
ShaderInput::StorageBuffer((), concrete!(Color)),
|
ShaderInput::StorageBuffer((), concrete!(PackedPixel)),
|
||||||
//ShaderInput::Constant(gpu_executor::GPUConstant::GlobalInvocationId),
|
//ShaderInput::Constant(gpu_executor::GPUConstant::GlobalInvocationId),
|
||||||
ShaderInput::OutputBuffer((), concrete!(Color)),
|
ShaderInput::OutputBuffer((), concrete!(PackedPixel)),
|
||||||
],
|
],
|
||||||
output: ShaderInput::OutputBuffer((), concrete!(Color)),
|
output: ShaderInput::OutputBuffer((), concrete!(PackedPixel)),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -202,6 +226,7 @@ async fn create_compute_pass_descriptor(node: DocumentNode, image: &ImageFrame<C
|
|||||||
return frame;*/
|
return frame;*/
|
||||||
log::debug!("creating buffer");
|
log::debug!("creating buffer");
|
||||||
let width_uniform = executor.create_uniform_buffer(image.image.width).unwrap();
|
let width_uniform = executor.create_uniform_buffer(image.image.width).unwrap();
|
||||||
|
let quantization_uniform = executor.create_uniform_buffer(QuantizationChannels::default()).unwrap();
|
||||||
let storage_buffer = executor
|
let storage_buffer = executor
|
||||||
.create_storage_buffer(
|
.create_storage_buffer(
|
||||||
image.image.data.clone(),
|
image.image.data.clone(),
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ use dyn_any::DynAny;
|
|||||||
pub struct AnyRefNode<'n, N: Node<'n>>(N, PhantomData<&'n ()>);
|
pub struct AnyRefNode<'n, N: Node<'n>>(N, PhantomData<&'n ()>);
|
||||||
|
|
||||||
impl<'n, N: Node<'n, Output = &'n O>, O: DynAny<'n> + 'n> Node<'n> for AnyRefNode<'n, N> {
|
impl<'n, N: Node<'n, Output = &'n O>, O: DynAny<'n> + 'n> Node<'n> for AnyRefNode<'n, N> {
|
||||||
type Output = &'n (dyn DynAny<'n>);
|
fn eval(&'n self) -> &'n (dyn DynAny<'n>) {
|
||||||
fn eval(&'n self) -> Self::Output {
|
|
||||||
let value: &O = self.0.eval();
|
let value: &O = self.0.eval();
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
@@ -22,8 +21,7 @@ impl<'n, N: Node<'n, Output = &'n O>, O: 'n + ?Sized> AnyRefNode<'n, N> {
|
|||||||
pub struct StorageNode<'n>(&'n dyn Node<'n, Output = &'n dyn DynAny<'n>>);
|
pub struct StorageNode<'n>(&'n dyn Node<'n, Output = &'n dyn DynAny<'n>>);
|
||||||
|
|
||||||
impl<'n> Node<'n> for StorageNode<'n> {
|
impl<'n> Node<'n> for StorageNode<'n> {
|
||||||
type Output = &'n (dyn DynAny<'n>);
|
fn eval(&'n self) -> &'n (dyn DynAny<'n>) {
|
||||||
fn eval(&'n self) -> Self::Output {
|
|
||||||
self.0.eval()
|
self.0.eval()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,7 +34,6 @@ impl<'n> StorageNode<'n> {
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct AnyValueNode<'n, T>(T, PhantomData<&'n ()>);
|
pub struct AnyValueNode<'n, T>(T, PhantomData<&'n ()>);
|
||||||
impl<'n, T: 'n + DynAny<'n>> Node<'n> for AnyValueNode<'n, T> {
|
impl<'n, T: 'n + DynAny<'n>> Node<'n> for AnyValueNode<'n, T> {
|
||||||
type Output = &'n dyn DynAny<'n>;
|
|
||||||
fn eval(&'n self) -> &'n dyn DynAny<'n> {
|
fn eval(&'n self) -> &'n dyn DynAny<'n> {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use graph_craft::imaginate_input::{ImaginateCache, ImaginateController, ImaginateMaskStartingFill, ImaginateSamplingMethod};
|
use graph_craft::imaginate_input::{ImaginateCache, ImaginateController, ImaginateMaskStartingFill, ImaginateSamplingMethod};
|
||||||
use graph_craft::proto::{NodeConstructor, TypeErasedBox};
|
use graph_craft::proto::{NodeConstructor, TypeErasedBox};
|
||||||
use graphene_core::ops::IdNode;
|
use graphene_core::ops::IdNode;
|
||||||
use graphene_core::quantization::QuantizationChannels;
|
use graphene_core::quantization::{QuantizationChannels, PackedPixel};
|
||||||
|
|
||||||
use graphene_core::raster::brush_cache::BrushCache;
|
use graphene_core::raster::brush_cache::BrushCache;
|
||||||
use graphene_core::raster::color::Color;
|
use graphene_core::raster::color::Color;
|
||||||
@@ -513,8 +513,8 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||||||
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")]
|
||||||
register_node!(graphene_std::quantization::GenerateQuantizationNode<_, _>, input: ImageFrame<Color>, params: [u32, u32]),
|
register_node!(graphene_std::quantization::GenerateQuantizationNode<_, _>, input: ImageFrame<Color>, params: [u32, u32]),
|
||||||
raster_node!(graphene_core::quantization::QuantizeNode<_>, params: [QuantizationChannels]),
|
register_node!(graphene_core::quantization::QuantizeNode<_>, input: Color, params: [QuantizationChannels]),
|
||||||
raster_node!(graphene_core::quantization::DeQuantizeNode<_>, params: [QuantizationChannels]),
|
register_node!(graphene_core::quantization::DeQuantizeNode<_>, input: PackedPixel, params: [QuantizationChannels]),
|
||||||
register_node!(graphene_core::ops::CloneNode<_>, input: &QuantizationChannels, params: []),
|
register_node!(graphene_core::ops::CloneNode<_>, input: &QuantizationChannels, params: []),
|
||||||
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: VectorData, params: [DVec2, f32, DVec2, DVec2, DVec2]),
|
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: VectorData, params: [DVec2, f32, DVec2, DVec2, DVec2]),
|
||||||
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: ImageFrame<Color>, params: [DVec2, f32, DVec2, DVec2, DVec2]),
|
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: ImageFrame<Color>, params: [DVec2, f32, DVec2, DVec2, DVec2]),
|
||||||
|
|||||||
Reference in New Issue
Block a user