Ejemplo n.º 1
0
 public virtual void Visit(DeclarationStatement declarationStatement)
 {
     WriteLinkLine(declarationStatement);
     VisitDynamic(declarationStatement.Content);
 }
Ejemplo n.º 2
0
 /// <inheritdoc />
 public override void Visit(DeclarationStatement declarationStatement)
 {
     WriteLinkLine(declarationStatement);
     VisitDynamic(declarationStatement.Content);
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Modify the Hull shader constant
        /// </summary>
        /// <param name="entryPoint">the entrypoint method</param>
        /// <param name="inStreamStructTypeName">the input structure of the Hull shader</param>
        /// <param name="outStreamStructTypeName">the output structure of the Hull shader</param>
        private void GenerateStreamsForHullShaderConstant(MethodDefinition entryPoint, TypeName inStreamStructTypeName, TypeName outStreamStructTypeName)
        {
            if (entryPoint != null)
            {
                var constStreamStruct = CreateStreamStructure(mainModuleMixin.VirtualTable.Variables.Select(x => x.Variable).Where(x => x.Qualifiers.Contains(ParadoxStorageQualifier.PatchStream)).Distinct().ToList<IDeclaration>(), "HS_CONSTANTS");
                var typeConst = new TypeName(constStreamStruct.Name);

                var visitedMethods = new Stack<MethodDeclaration>();
                RecursiveRename(entryPoint, inStreamStructTypeName, outStreamStructTypeName, outStreamStructTypeName, typeConst, visitedMethods);

                // get the Constants parameter, its name and remove it
                var constParamName = "constants";
                var constParam = entryPoint.Parameters.FirstOrDefault(x => x.Type.Name.Text == constStreamStruct.Name.Text);
                if (constParam != null)
                {
                    constParamName = constParam.Name.Text;
                    entryPoint.Parameters.Remove(constParam); // remove the parameter
                }

                var constDecl = new DeclarationStatement(
                    new Variable(typeConst, constParamName)
                        {
                            InitialValue = new CastExpression { From = new LiteralExpression(0), Target = new TypeName(constStreamStruct.Name) }
                        });

                entryPoint.Body.Insert(0, constDecl); // insert structure instance declaration
                entryPoint.Body.Add(new ReturnStatement(new VariableReferenceExpression(constParamName))); // add a return statement

                entryPoint.ReturnType = typeConst; // change the return type

                shader.Members.Insert(0, constStreamStruct);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Creates assignement statements with its default value
        /// </summary>
        /// <param name="streamStruct">the stream structure</param>
        /// <param name="streamName">the name of the stream</param>
        /// <param name="inputStruct">the input structure</param>
        /// <param name="initialValue">the initial value</param>
        /// <param name="scopeStack">???</param>
        /// <returns>A collection of statements</returns>
        private static IEnumerable<Statement> AssignStreamFromInput(StructType streamStruct, string streamName, StructType inputStruct, Expression initialValue, bool basicTransformation)
        {
            foreach (var currentField in inputStruct.Fields)
            {
                // Ignore fields that don't exist in Streams.
                // It could happen if HSConstantMain references a stream (gets added to HS_OUTPUT),
                // and in HSMain CreateStreamFromInput() is called (this stream doesn't exist in DS_STREAMS).
                if (streamStruct.Fields.All(x => x.Name != currentField.Name))
                    continue;

                // If we have a scope stack (advanced analysis), then convert expression by appending
                // field to each reference to a variable of inputStruct type
                // i.e. "output = input1 * 3 + input2 * 5" will become "output.A = input1.A * 3 + input2.A * 5"
                // Otherwise consider it is as a simple a variable reference and directly append field.
                if (basicTransformation)
                {
                    yield return new ExpressionStatement(
                        new AssignmentExpression(
                            AssignmentOperator.Default,
                            new MemberReferenceExpression(new VariableReferenceExpression(streamName), currentField.Name),
                            new MemberReferenceExpression(initialValue, currentField.Name)));
                }
                else
                {
                    //yield return AssignStreamFieldFromInput(streamName, inputStruct, initialValue, scopeStack, currentField);
                    foreach (var field in streamStruct.Fields.Where(x => x.Name == currentField.Name)) // TODO: where might be useless
                    {
                        if (field.Type is ArrayType)
                        {
                            //create a for loop

                            var iteratorName = field.Name.Text + "_Iter";
                            var iterator = new Variable(ScalarType.Int, iteratorName, new LiteralExpression(0));
                            var start = new DeclarationStatement(iterator);
                            var condition = new BinaryExpression(BinaryOperator.Less, new VariableReferenceExpression(iterator), (field.Type as ArrayType).Dimensions[0]);
                            var next = new UnaryExpression(UnaryOperator.PreIncrement, new VariableReferenceExpression(iterator));
                            var forLoop = new ForStatement(start, condition, next);

                            var fieldAssigner = new StreamFieldVisitor(field, new VariableReferenceExpression(iterator));
                            var clonedExpression = fieldAssigner.Run(ParadoxAssignmentCloner.Run(initialValue));
                            
                            forLoop.Body = new ExpressionStatement(
                                new AssignmentExpression(
                                    AssignmentOperator.Default,
                                    new IndexerExpression(new MemberReferenceExpression(new VariableReferenceExpression(streamName), currentField.Name), new VariableReferenceExpression(iterator)),
                                    clonedExpression));

                            yield return forLoop;
                        }
                        else
                        {
                            var fieldAssigner = new StreamFieldVisitor(field);
                            //var clonedExpression = fieldAssigner.Run(initialValue.DeepClone());
                            var clonedExpression = fieldAssigner.Run(ParadoxAssignmentCloner.Run(initialValue));
                            
                            yield return new ExpressionStatement(
                                new AssignmentExpression(
                                    AssignmentOperator.Default,
                                    new MemberReferenceExpression(new VariableReferenceExpression(streamName), currentField.Name),
                                    clonedExpression));
                        }
                    }
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Generates a stream structure and add them to the Ast - for the geometry shader
        /// </summary>
        /// <param name="entryPoint">the entrypoint function</param>
        /// <param name="streamStageUsage">the stream usage in this stage</param>
        /// <param name="stageName">the name of the stage</param>
        /// <param name="prevOuputStructure">the output structutre from the previous stage</param>
        /// <returns>the new output structure</returns>
        private StructType GenerateStreamsWithSpecialDataInput(MethodDefinition entryPoint, StreamStageUsage streamStageUsage, string stageName, StructType prevOuputStructure)
        {
            if (entryPoint != null)
            {
                var inStreamStruct = prevOuputStructure ?? CreateStreamStructure(streamStageUsage.InStreamList, stageName + "_INPUT");
                var outStreamStruct = CreateStreamStructure(streamStageUsage.OutStreamList, stageName + "_OUTPUT");

                var mixin = entryPoint.GetTag(ParadoxTags.ShaderScope) as ModuleMixin;

                var intermediateStreamStruct = CreateIntermediateStructType(streamStageUsage, stageName);

                // put the streams declaration at the beginning of the method body
                var streamsDeclaration = new DeclarationStatement(new Variable(new TypeName(intermediateStreamStruct.Name), "streams") { InitialValue = new CastExpression { From = new LiteralExpression(0), Target = new TypeName(intermediateStreamStruct.Name) } });
                entryPoint.Body.Insert(0, streamsDeclaration);

                // add the declaration statements to the entrypoint and fill with the values
                var outputStatements = CreateOutputFromStream(outStreamStruct, "output", intermediateStreamStruct, "streams").ToList();
                var outputVre = new VariableReferenceExpression(((outputStatements.First() as DeclarationStatement).Content as Variable).Name);

                var replacor = new ParadoxReplaceAppend(streamAnalyzer.AppendMethodCalls, outputStatements, outputVre);
                ReplaceAppendMethod(entryPoint, replacor);
                
                var visitedMethods = new Stack<MethodDeclaration>();
                var inStructType = new TypeName(inStreamStruct.Name);
                var outStructType = new TypeName(outStreamStruct.Name);
                RecursiveRename(entryPoint, inStructType, null, outStructType, null, visitedMethods);

                // explore all the called functions
                var streamsVisitedMethods = new HashSet<MethodDeclaration>();
                var methodsWithStreams = new List<MethodDeclaration>();
                PropagateStreamsParameter(entryPoint, inStreamStruct, intermediateStreamStruct, outStreamStruct, streamsVisitedMethods, methodsWithStreams);

                CheckCrossStageMethodCall(streamStageUsage.ShaderStage, methodsWithStreams);

                if (prevOuputStructure == null)
                    shader.Members.Insert(0, inStreamStruct);
                shader.Members.Insert(0, outStreamStruct);
                shader.Members.Insert(0, intermediateStreamStruct);

                return outStreamStruct;
            }

            return prevOuputStructure;
        }