Browse Source

Node shader optimization wip

flabbet 8 months ago
parent
commit
a5b1b3f6d0

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit 05bb1b70b93fdef0b944c13f0dbe50e1baea0559
+Subproject commit 73622d14f4a7e89f036ecec5bfe74cae15708348

+ 81 - 8
src/PixiEditor.ChangeableDocument/Changeables/Graph/Context/FuncContext.cs

@@ -30,6 +30,8 @@ public class FuncContext
     public RenderContext RenderContext { get; set; }
 
     public ShaderBuilder Builder { get; set; }
+    
+    private Dictionary<IFuncInputProperty, ShaderExpressionVariable> _cachedValues = new();
 
     public void ThrowOnMissingContext()
     {
@@ -52,7 +54,7 @@ public class FuncContext
         SamplePosition = Builder.ConstructFloat2(OriginalPosition.X, OriginalPosition.Y); 
     }
 
-    public Half4 SampleSurface(DrawingSurface surface, Float2 pos)
+    public Half4 SampleSurface(DrawingSurface surface, Expression pos)
     {
         SurfaceSampler texName = Builder.AddOrGetSurface(surface);
         return Builder.Sample(texName, pos);
@@ -194,11 +196,22 @@ public class FuncContext
                 return new Float1(uniformName);
             }
         }
+        
+        if (_cachedValues.TryGetValue(getFrom, out ShaderExpressionVariable cachedValue))
+        {
+            if (cachedValue is Float1 float1)
+            {
+                return float1;
+            }
+        }
 
-        return getFrom.Value(this);
+        var val = getFrom.Value(this);
+        _cachedValues[getFrom] = val;
+        
+        return val;
     }
 
-    public Expression GetValue(FuncInputProperty<Int1> getFrom)
+    public Int1 GetValue(FuncInputProperty<Int1> getFrom)
     {
         if (HasContext)
         {
@@ -206,11 +219,22 @@ public class FuncContext
             {
                 string uniformName = $"int_{Builder.GetUniqueNameNumber()}";
                 Builder.AddUniform(uniformName, (int)getFrom.Value(this).ConstantValue);
-                return new Expression(uniformName);
+                return new Int1(uniformName);
+            }
+        }
+        
+        if (_cachedValues.TryGetValue(getFrom, out ShaderExpressionVariable cachedValue))
+        {
+            if (cachedValue is Int1 int1)
+            {
+                return int1;
             }
         }
 
-        return getFrom.Value(this);
+        var val = getFrom.Value(this);
+        _cachedValues[getFrom] = val;
+        
+        return val;
     }
 
     private static bool IsFuncType<T>(FuncInputProperty<T> getFrom)
@@ -218,7 +242,7 @@ public class FuncContext
         return getFrom.Connection.ValueType.IsAssignableTo(typeof(Delegate));
     }
 
-    public ShaderExpressionVariable GetValue(FuncInputProperty<Half4> getFrom)
+    public Half4 GetValue(FuncInputProperty<Half4> getFrom)
     {
         if (HasContext)
         {
@@ -230,8 +254,19 @@ public class FuncContext
                 return color;
             }
         }
+        
+        if (_cachedValues.TryGetValue(getFrom, out ShaderExpressionVariable cachedValue))
+        {
+            if (cachedValue is Half4 half4)
+            {
+                return half4;
+            }
+        }
 
-        return getFrom.Value(this);
+        var val = getFrom.Value(this);
+        _cachedValues[getFrom] = val;
+        
+        return val;
     }
 
     public Float2 GetValue(FuncInputProperty<Float2> getFrom)
@@ -246,7 +281,45 @@ public class FuncContext
                 return value;
             }
         }
+        
+        if (_cachedValues.TryGetValue(getFrom, out ShaderExpressionVariable cachedValue))
+        {
+            if (cachedValue is Float2 float2)
+            {
+                return float2;
+            }
+        }
+
+        var val = getFrom.Value(this);
+        _cachedValues[getFrom] = val;
+        
+        return val;
+    }
+
+    public Int2 GetValue(FuncInputProperty<Int2>? getFrom)
+    {
+        if (HasContext)
+        {
+            if (getFrom?.Connection == null || !IsFuncType(getFrom))
+            {
+                Int2 value = getFrom.Value(this);
+                value.VariableName = $"int2_{Builder.GetUniqueNameNumber()}";
+                Builder.AddUniform(value.VariableName, value.ConstantValue);
+                return value;
+            }
+        }
+        
+        if (_cachedValues.TryGetValue(getFrom, out ShaderExpressionVariable cachedValue))
+        {
+            if (cachedValue is Int2 int2)
+            {
+                return int2;
+            }
+        }
 
-        return getFrom.Value(this);
+        var val = getFrom.Value(this);
+        _cachedValues[getFrom] = val;
+        
+        return val;
     }
 }

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/SeparateColorNode.cs

@@ -56,7 +56,7 @@ public class SeparateColorNode : Node
         };
 
     private Half4 GetRgba(FuncContext ctx) => 
-        contextVariables.GetOrAttachNew(ctx, Color, () => Color.Value(ctx));
+        contextVariables.GetOrAttachNew(ctx, Color, () => ctx.GetValue(Color));
 
     private Half4 GetHsva(FuncContext ctx) =>
         contextVariables.GetOrAttachNew(ctx, Color, () => ctx.RgbaToHsva(ctx.GetValue(Color)));

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/SeparateVecDNode.cs

@@ -17,8 +17,8 @@ public class SeparateVecDNode : Node
     
     public SeparateVecDNode()
     {
-        X = CreateFuncOutput("X", "X", ctx => Vector.Value(ctx).X);
-        Y = CreateFuncOutput("Y", "Y", ctx => Vector.Value(ctx).Y);
+        X = CreateFuncOutput<Float1>("X", "X", ctx => ctx.GetValue(Vector).X);
+        Y = CreateFuncOutput("Y", "Y", ctx => ctx.GetValue(Vector).Y);
         Vector = CreateFuncInput<Float2>("Vector", "VECTOR", VecD.Zero);
     }
 

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/SeparateVecINode.cs

@@ -16,8 +16,8 @@ public class SeparateVecINode : Node
     
     public SeparateVecINode()
     {
-        X = CreateFuncOutput<Int1>("X", "X", ctx => Vector.Value(ctx).X);
-        Y = CreateFuncOutput<Int1>("Y", "Y", ctx => Vector.Value(ctx).Y);
+        X = CreateFuncOutput<Int1>("X", "X", ctx => ctx.GetValue(Vector).X);
+        Y = CreateFuncOutput<Int1>("Y", "Y", ctx => ctx.GetValue(Vector).Y);
         Vector = CreateFuncInput<Int2>("Vector", "VECTOR", new VecI(0, 0));
     }
 

+ 4 - 3
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/MathNode.cs

@@ -4,6 +4,7 @@ using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.ChangeableDocument.Rendering;
 using Drawie.Backend.Core;
+using Drawie.Backend.Core.Shaders.Generation;
 using Drawie.Backend.Core.Shaders.Generation.Expressions;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
@@ -55,8 +56,8 @@ public class MathNode : Node
             return context.NewFloat1(result);
         }
 
-        var xConst = x.ConstantValue;
-        var yConst = y.ConstantValue;
+        var xConst = (x.GetConstant() as Float1)?.ConstantValue ?? 0;
+        var yConst = (y.GetConstant() as Float1)?.ConstantValue ?? 0;
             
         var constValue = Mode.Value switch
         {
@@ -72,7 +73,7 @@ public class MathNode : Node
         return new Float1(string.Empty) { ConstantValue = constValue };
     }
 
-    private (Float1 xConst, Float1 y) GetValues(FuncContext context)
+    private (ShaderExpressionVariable xConst, ShaderExpressionVariable y) GetValues(FuncContext context)
     {
         return (context.GetValue(X), context.GetValue(Y));
     }

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/SampleImageNode.cs

@@ -33,7 +33,7 @@ public class SampleImageNode : Node
             return new Half4("");
         }
 
-        Float2 uv = context.GetValue(Coordinate);
+        Expression uv = context.GetValue(Coordinate);
 
         return context.SampleSurface(Image.Value.DrawingSurface, uv);
     }