protected override Expression VisitBinary(BinaryExpression node) { switch (node.NodeType) { case ExpressionType.ArrayIndex: Visit(node.Left); GlslVariable variable = _bufferVariables.Pop(); _shader.Main.Append(variable.Name); _shader.Main.Append("["); Visit(node.Right); _shader.Main.Append("]"); break; case ExpressionType.Multiply: Visit(node.Right); _shader.Main.Append($" {node.NodeType.GlslSymbol()} "); Visit(node.Left); break; default: Visit(node.Left); _shader.Main.Append($" {node.NodeType.GlslSymbol()} "); Visit(node.Right); break; } return(node); }
protected override Expression VisitParameter(ParameterExpression node) { EnsureTypeAdded(node.Type); GlslVariable variable = _lambdaParamToBufferMap[node.Name]; string srcName = variable.Name; while (_parameterMemberChain.Count > 0) { MemberInfo member = _parameterMemberChain.Pop(); srcName += "." + member.GlslName(); } _shader.Main.Append(srcName); return(node); }
public VulkanComputeContext Translate(Expression expression, VulkanDevice device) { _device = device; _shader = new GlslComputeShader(); _ctx = new VulkanComputeContext(device); Visit(expression); _ctx.Output = ResolveOutput(_ctx.Inputs[0].Count, expression); GlslVariable outputVar = _shader.AddBuffer(_ctx.Output.ElementType, false, true); _shader.Main.AppendLine($"{outputVar.Name} = {SrcVariable.Name};"); _ctx.SpirV = _shader.CompileToSpirV(); return(_ctx); }
private bool HandleQueryMethodCall(MethodCallExpression node) { if (node.Method.DeclaringType != typeof(Queryable)) { return(false); } switch (node.Method.Name) { case nameof(Queryable.Select): // Implements LINQ Select query operator. { Visit(node.Arguments[0]); DstVariable = GlslVariable.Next(node.Type.GenericTypeArguments[0]); _shader.Main.Append($"{DstVariable.Type.GlslName()} {DstVariable.Name} = "); _parameterMemberChain.Clear(); _lambdaParamToBufferMap.Clear(); var lambda = (LambdaExpression)node.Arguments[1].StripQuotes(); _lambdaParamToBufferMap.Add(lambda.Parameters[0].Name, _bufferVariables.Pop()); _isBufferStartOfChain = false; Visit(lambda.Body); if (!_shader.Main.IsNewline) { _shader.Main.AppendLine(";"); } _bufferVariables.Push(DstVariable); SrcVariable = DstVariable; return(true); } case nameof(Queryable.Zip): // Implements LINQ Zip query operator. { Visit(node.Arguments[0]); Visit(node.Arguments[1]); DstVariable = GlslVariable.Next(node.Type.GenericTypeArguments[0]); _shader.Main.Append($"{DstVariable.Type.GlslName()} {DstVariable.Name} = "); _parameterMemberChain.Clear(); _lambdaParamToBufferMap.Clear(); var lambda = (LambdaExpression)node.Arguments[2].StripQuotes(); _lambdaParamToBufferMap.Add(lambda.Parameters[1].Name, _bufferVariables.Pop()); _lambdaParamToBufferMap.Add(lambda.Parameters[0].Name, _bufferVariables.Pop()); _isBufferStartOfChain = false; Visit(lambda.Body); if (!_shader.Main.IsNewline) { _shader.Main.AppendLine(";"); } _bufferVariables.Push(DstVariable); SrcVariable = DstVariable; return(true); } default: { return(false); } } }