Exemple #1
0
        public bool TryCallIntrinsicsFunction(FunctionKey functionKey, CSharpSyntaxNode selfExpressionNode, IEnumerable <CSharpSyntaxNode> arguments)
        {
            var instrinsicDelegate = mFrontEnd.mCurrentLibrary.FindIntrinsicFunction(functionKey);

            if (instrinsicDelegate == null)
            {
                return(false);
            }

            // Build the arguments up
            var argumentIRs = new List <IShaderIR>();

            // Visit the self if it exists
            if (selfExpressionNode != null)
            {
                var selfOp = WalkAndGetResult(selfExpressionNode);
                argumentIRs.Add(selfOp);
            }
            // Visit all the args if they exist
            if (arguments != null)
            {
                foreach (var argument in arguments)
                {
                    argumentIRs.Add(WalkAndGetResult(argument));
                }
            }
            instrinsicDelegate(mFrontEnd, argumentIRs, mContext);
            return(true);
        }
Exemple #2
0
        public void DefaultConstructType(INamedTypeSymbol typeSymbol, ShaderOp variableOp)
        {
            var defaultConstructorSymbol = FindDefaultConstructorSymbol(typeSymbol);

            if (defaultConstructorSymbol == null)
            {
                return;
            }

            var constructorKey = new FunctionKey(defaultConstructorSymbol);
            // If this is an intrinsic (defined by the compiler and not user defined) then invoke it.
            var constructorIntrinsic = mFrontEnd.mCurrentLibrary.FindIntrinsicFunction(constructorKey);

            if (constructorIntrinsic != null)
            {
                constructorIntrinsic(mFrontEnd, new List <IShaderIR>(), mContext);
                mFrontEnd.CreateStoreOp(mContext.mCurrentBlock, variableOp, mContext.Pop());
                return;
            }
            // Otherwise see if this is user defined
            var constructorFn = mFrontEnd.mCurrentLibrary.FindFunction(constructorKey);

            if (constructorFn != null)
            {
                mFrontEnd.GenerateFunctionCall(constructorFn, variableOp, null, mContext);
                return;
            }

            var derefType    = variableOp.mResultType.GetDereferenceType();
            var defaultValue = mFrontEnd.DefaultConstructPrimitive(derefType, mContext);

            mFrontEnd.CreateStoreOp(mContext.mCurrentBlock, variableOp, defaultValue);
        }
Exemple #3
0
        public ShaderFunction CreateFunction(FunctionKey key)
        {
            ShaderFunction shaderFunction = new ShaderFunction();

            mFunctionMap.Add(key, shaderFunction);
            return(shaderFunction);
        }
Exemple #4
0
        public ShaderFunction FindOrCreateFunction(FunctionKey key, bool checkDependencies = true)
        {
            var result = FindFunction(key, checkDependencies);

            if (result == null)
            {
                result = CreateFunction(key);
            }
            return(result);
        }
Exemple #5
0
        public ShaderFunction FindFunction(FunctionKey key, bool checkDependencies = true)
        {
            var result = mFunctionMap.GetValueOrDefault(key);

            if (result == null && checkDependencies && mDependencies != null)
            {
                result = mDependencies.FindFunction(key, checkDependencies);
            }
            return(result);
        }
Exemple #6
0
 public ShaderFunction FindFunction(FunctionKey key, bool checkDependencies = true)
 {
     foreach (var library in this)
     {
         var result = library.FindFunction(key, checkDependencies);
         if (result != null)
         {
             return(result);
         }
     }
     return(null);
 }
Exemple #7
0
        public override void VisitObjectCreationExpression(ObjectCreationExpressionSyntax node)
        {
            var symbol       = GetSymbol(node);
            var fnKey        = new FunctionKey(symbol);
            var resultSymbol = GetSymbol(node.Type);
            var resultType   = mFrontEnd.mCurrentLibrary.FindType(new TypeKey(resultSymbol));

            // Handle constructing intrinsics types
            if (TryCallIntrinsicsFunction(fnKey, null, node.ArgumentList.Arguments))
            {
                return;
            }

            var fieldPtrType    = resultType.FindPointerType(StorageClass.Function);
            var localVariableOp = mFrontEnd.CreateOpVariable(fieldPtrType, mContext);

            localVariableOp.DebugInfo.Name = "temp" + resultType.mMeta.mName;

            var shaderFunction = mFrontEnd.mCurrentLibrary.FindFunction(fnKey);

            if (shaderFunction == null && node.ArgumentList.Arguments.Count != 0)
            {
                throw new Exception("Failed to find function");
            }

            // If this is a function call then invoke it
            if (shaderFunction != null)
            {
                var arguments = new List <CSharpSyntaxNode>();
                foreach (var arg in node.ArgumentList.Arguments)
                {
                    arguments.Add(arg);
                }
                GenerateFunctionCall(shaderFunction, localVariableOp, arguments);
            }

            // If there's an initializer expression then visit each one
            if (node.Initializer != null)
            {
                // The context of 'this' changes for the initializer expression
                var thisOp = mContext.mThisOp;
                mContext.mThisOp = localVariableOp;
                foreach (var initExpression in node.Initializer.Expressions)
                {
                    Visit(initExpression);
                }
                mContext.mThisOp = thisOp;
            }

            mContext.Push(localVariableOp);
        }
Exemple #8
0
        public bool TryCallSetterFunction(FunctionKey functionKey, IShaderIR selfInstanceIR, IShaderIR rhsIR)
        {
            var setterShaderFunction = mFrontEnd.mCurrentLibrary.FindFunction(functionKey);

            if (setterShaderFunction == null)
            {
                return(false);
            }

            GenerateFunctionCall(setterShaderFunction, selfInstanceIR, new List <IShaderIR>()
            {
                rhsIR
            });
            return(true);
        }
Exemple #9
0
        public bool TryCallIntrinsicsSetterFunction(FunctionKey functionKey, IShaderIR setter, IShaderIR argumentIR)
        {
            var instrinsicDelegate = mFrontEnd.mCurrentLibrary.FindIntrinsicSetterFunction(functionKey);

            if (instrinsicDelegate == null)
            {
                return(false);
            }

            // Build the arguments up
            var argumentIRs = new List <IShaderIR>();

            instrinsicDelegate(mFrontEnd, setter, argumentIR, mContext);

            return(true);
        }
Exemple #10
0
        public InstrinsicSetterDelegate FindIntrinsicSetterFunction(FunctionKey key, bool checkDependencies = true)
        {
            var result = IntrinsicSetterFunctions.GetValueOrDefault(key, null);

            if (result == null && mDependencies != null)
            {
                foreach (var dependency in mDependencies)
                {
                    result = dependency.FindIntrinsicSetterFunction(key, checkDependencies);
                    if (result != null)
                    {
                        break;
                    }
                }
            }
            return(result);
        }
Exemple #11
0
        public bool TryCallFunction(FunctionKey functionKey, CSharpSyntaxNode selfExpressionNode, CSharpSyntaxNode rhsNode)
        {
            var setterShaderFunction = mFrontEnd.mCurrentLibrary.FindFunction(functionKey);

            if (setterShaderFunction == null)
            {
                return(false);
            }

            var selfInstanceIR = WalkAndGetResult(selfExpressionNode);
            var rhsIR          = WalkAndGetResult(rhsNode);

            GenerateFunctionCall(setterShaderFunction, selfInstanceIR, new List <IShaderIR>()
            {
                rhsIR
            });
            return(true);
        }
Exemple #12
0
        public override void VisitAssignmentExpression(AssignmentExpressionSyntax node)
        {
            // Always get the right IR but not always the left. In some cases with setters we don't need the left. This avoids loading the left twice.
            IShaderIR leftIR  = null;
            IShaderIR rightIR = WalkAndGetResult(node.Right);

            // If the token isn't the assignment op, then this must be a compound assignment (e.g. '+=').
            var token = node.OperatorToken.Text;

            if (token != "=")
            {
                // To do the compound we have to load the left now.
                leftIR = WalkAndGetResult(node.Left);
                var lhsType = GetSymbolType(node.Left);
                var rhsType = GetSymbolType(node.Right);

                // Generate the token for the binary op in the compound (just strip the '=' off) and then visit the binary expression.
                var binaryOp = token.Substring(0, token.Length - 1);
                VisitBinaryExpression(node, lhsType, leftIR, rhsType, rightIR, binaryOp);
                // Do whatever remaining logic for the assignment with the result of the binary expression.
                rightIR = mContext.Pop();
            }

            // If the left side is actually a setter, then we have to flip the assignment around to call the setter
            var leftSymbol = GetSymbol(node.Left);

            // One complicated case is if the left is actually a member access (e.g. Vec3.XY = rhs).
            // In this case, we need to call the setter on Vec3 (the expression of the member access)
            if (node.Left is MemberAccessExpressionSyntax memberAccessNode && leftSymbol.IsStatic == false)
            {
                FunctionKey functionKey = null;
                // Try and get the function key for this symbol depending on if it's a field, property, etc...
                if (leftSymbol is IPropertySymbol propertySymbol && !propertySymbol.IsReadOnly)
                {
                    functionKey = new FunctionKey(propertySymbol.SetMethod);
                }
 /// <summary>
 /// Creates a simple intrinsic function (one whos ops are just value types of the args one-for-one) callback for the given symbol information.
 /// </summary>
 static public void CreateSimpleIntrinsicFunction(FrontEndTranslator translator, FunctionKey functionKey, OpInstructionType opType, ShaderType returnType)
 {
     ShaderLibrary.InstrinsicDelegate callback = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) =>
     {
         SimpleValueTypeIntrinsic(translator, context, opType, returnType, arguments);
     };
     translator.mCurrentLibrary.CreateIntrinsicFunction(functionKey, callback);
 }
Exemple #14
0
 public void CreateIntrinsicSetterFunction(FunctionKey key, InstrinsicSetterDelegate intrinsic)
 {
     IntrinsicSetterFunctions.TryAdd(key, intrinsic);
 }
Exemple #15
0
 //---------------------------------------------------------------Functions
 public bool AddFunction(FunctionKey key, ShaderFunction shaderFunction)
 {
     return(mFunctionMap.TryAdd(key, shaderFunction));
 }