コード例 #1
0
        /// <summary>
        /// Generates a stream structure and add them to the Ast - for the hull shader and hull shader constant
        /// </summary>
        /// <param name="entryPoint">the entrypoint function</param>
        /// <param name="entryPointHSConstant">entrypoint for the hull shader constant</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 GenerateStreamsForHullShader(MethodDefinition entryPoint, MethodDefinition entryPointHSConstant, StreamStageUsage streamStageUsage, string stageName, StructType prevOuputStructure)
        {
            if (entryPoint != null)
            {
                // same behavior as geometry shader
                var outStreamStruct = GenerateStreamsWithSpecialDataInput(entryPoint, streamStageUsage, stageName, prevOuputStructure);
                var inStreamStruct = prevOuputStructure ?? shader.Members.OfType<StructType>().FirstOrDefault(x => x.Name.Text == stageName + "_INPUT");
                var intermediateStreamStruct = shader.Members.OfType<StructType>().FirstOrDefault(x => x.Name.Text == stageName + "_STREAMS");

                if (inStreamStruct == null)
                    throw new Exception("inStreamStruct cannot be null");

                var inStructType = new TypeName(inStreamStruct.Name);
                var outStructType = new TypeName(outStreamStruct.Name);

                // get the Output parameter, its name and remove it
                var outputName = "output";
                var outputParam = entryPoint.Parameters.FirstOrDefault(x => x.Type.Name.Text == outStreamStruct.Name.Text);
                if (outputParam != null)
                {
                    outputName = outputParam.Name.Text; // get the name of the parameter
                    entryPoint.Parameters.Remove(outputParam); // remove the parameter
                }

                entryPoint.Body.Add(new ReturnStatement { Value = new VariableReferenceExpression(outputName) });
                entryPoint.Body.Insert(0, CreateStructInit(outStreamStruct, outputName));
                entryPoint.ReturnType = outStructType;

                if (entryPointHSConstant != null)
                    GenerateStreamsForHullShaderConstant(entryPointHSConstant, inStructType, outStructType);

                return outStreamStruct;
            }

            return prevOuputStructure;
        }
コード例 #2
0
        /// <summary>
        /// Generates a stream structure and add them to the Ast - for the domain 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 GenerateStreamsForDomainShader(MethodDefinition entryPoint, StreamStageUsage streamStageUsage, string stageName, StructType prevOuputStructure)
        {
            if (entryPoint != null)
            {
                var outStreamStruct = GenerateStreamsForHullShader(entryPoint, null, streamStageUsage, stageName, prevOuputStructure);

                var visitedMethods = new Stack<MethodDeclaration>();
                RecursiveRename(entryPoint, null, null, null, new TypeName("HS_CONSTANTS"), visitedMethods);

                return outStreamStruct;
            }

            return prevOuputStructure;
        }
コード例 #3
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(XenkoTags.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 XenkoReplaceAppend(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;
        }
コード例 #4
0
        /// <summary>
        /// Generates a stream structure and add them to the Ast
        /// </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 GenerateStreams(MethodDefinition entryPoint, StreamStageUsage streamStageUsage, string stageName, StructType prevOuputStructure, bool autoGenSem = true)
        {
            if (entryPoint != null)
            {
                // create the stream structures
                var inStreamStruct = prevOuputStructure ?? CreateStreamStructure(streamStageUsage.InStreamList, stageName + "_INPUT");
                var outStreamStruct = CreateStreamStructure(streamStageUsage.OutStreamList, stageName + "_OUTPUT", true, autoGenSem);

                var intermediateStreamStruct = CreateIntermediateStructType(streamStageUsage, stageName);

                // modify the entrypoint
                if (inStreamStruct.Fields.Count != 0)
                {
                    entryPoint.Parameters.Add(new Parameter(new TypeName(inStreamStruct.Name), "__input__"));
                    entryPoint.Parameters[0].Qualifiers.Values.Remove(ParameterQualifier.InOut);
                }

                // add the declaration statements to the entrypoint and fill with the values
                entryPoint.Body.InsertRange(0, CreateStreamFromInput(intermediateStreamStruct, "streams", inStreamStruct, new VariableReferenceExpression("__input__")));
                if (outStreamStruct.Fields.Count != 0)
                {
                    entryPoint.Body.AddRange(CreateOutputFromStream(outStreamStruct, "__output__", intermediateStreamStruct, "streams"));
                    entryPoint.Body.Add(new ReturnStatement { Value = new VariableReferenceExpression("__output__") });
                    entryPoint.ReturnType = new TypeName(outStreamStruct.Name);
                }

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

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

                return outStreamStruct;
            }

            return prevOuputStructure;
        }
コード例 #5
0
 /// <summary>
 /// Organize the streams for the compute shader
 /// </summary>
 /// <param name="streamStageUsage">the StreamStageUsage of the compute stage</param>
 private void ComputeShaderStreamAnalysis(StreamStageUsage streamStageUsage)
 {
     if (streamStageUsage.ShaderStage == XkShaderStage.Compute)
     {
         streamStageUsage.InterStreamList.AddRange(streamStageUsage.OutStreamList);
         streamStageUsage.OutStreamList.Clear();
     }
 }
コード例 #6
0
        /// <summary>
        /// Get the streams usage for this entrypoint
        /// </summary>
        /// <param name="moduleMixin">the current module mixin</param>
        /// <param name="entryPoint">the entrypoint method</param>
        /// <returns>a StreamStageUsage containing the streams usages</returns>
        private StreamStageUsage StreamAnalysisPerShader(ModuleMixin moduleMixin, MethodDeclaration entryPoint, XkShaderStage shaderStage)
        {
            var visitedMethods = new List<MethodDeclaration>();
            var streamStageUsage = new StreamStageUsage { ShaderStage = shaderStage };
            FindStreamsUsage(entryPoint, streamStageUsage.InStreamList, streamStageUsage.OutStreamList, visitedMethods);
            visitedMethods.Clear();

            return streamStageUsage;
        }
コード例 #7
0
 /// <summary>
 /// Creates an intermediate structure given the stream usage
 /// </summary>
 /// <param name="streamStageUsage">the StreamStageUsage</param>
 /// <param name="stageName">the name of the stage</param>
 /// <returns>the intermediate stream structure</returns>
 private static StructType CreateIntermediateStructType(StreamStageUsage streamStageUsage, string stageName)
 {
     var tempList = new List<IDeclaration>();
     tempList.AddRange(streamStageUsage.InStreamList);
     tempList.AddRange(streamStageUsage.InterStreamList);
     tempList.AddRange(streamStageUsage.OutStreamList);
     return CreateStreamStructure(tempList.Distinct().ToList(), stageName + "_STREAMS", false, false);
 }