Exemple #1
0
 static void ParseInstructions(IrPass pass, IEnumerable <InstructionToken> instructions)
 {
     foreach (var token in instructions)
     {
         pass.Instructions.Add(ParseInstruction(token));
     }
 }
Exemple #2
0
        /// <summary>
        /// Split instructions into seperate phases.
        /// </summary>
        /// <param name="programChunk"></param>
        static void ParseShaderChunk(IrShader shader, ShaderProgramChunk programChunk)
        {
            Func <OpcodeToken, int, bool> NotSplitToken = (OpcodeToken token, int index) =>
                                                          index == 0 ||
                                                          token.Header.OpcodeType != OpcodeType.HsForkPhase &&
                                                          token.Header.OpcodeType != OpcodeType.HsJoinPhase &&
                                                          token.Header.OpcodeType != OpcodeType.Label;
            int i = 0;

            while (i < programChunk.Tokens.Count)
            {
                var tokens = programChunk.Tokens.Skip(i).TakeWhile(NotSplitToken).ToList();
                if (i == 0)
                {
                    var type = programChunk.Version.ProgramType.GetPassType();
                    var pass = new IrPass(tokens, programChunk.Version.ProgramType.ToString(), type);
                    InstructionParser.ParseTokens(pass, tokens);
                    pass.InputSignature  = shader.Signatures.First(s => s.SignatureType == IrSignatureType.Input);
                    pass.OutputSignature = shader.Signatures.First(s => s.SignatureType == IrSignatureType.Output);
                    shader.Passes.Add(pass);
                }
                else if (tokens[0].Header.OpcodeType == OpcodeType.Label)
                {
                    var index = (tokens[0] as InstructionToken).Operands[0].Indices[0].Value;
                    var pass  = new IrPass($"Label{index}", IrPass.PassType.FunctionBody);
                    InstructionParser.ParseTokens(pass, tokens);
                    shader.Passes.Add(pass);
                }
                else if (tokens[0].Header.OpcodeType == OpcodeType.HsForkPhase)
                {
                    var index = shader.Passes.Select(p => p.Type == IrPass.PassType.HullShaderForkPhase).Count();
                    var pass  = new IrPass($"HullForkPhase{index}", IrPass.PassType.HullShaderForkPhase);
                    InstructionParser.ParseTokens(pass, tokens);
                    shader.Passes.Add(pass);
                }
                else
                {
                    var index = shader.Passes.Select(p => p.Type == IrPass.PassType.HullShaderJoinPhase).Count();
                    var pass  = new IrPass(tokens, $"HullJoinPhase{index}", IrPass.PassType.HullShaderJoinPhase);
                    InstructionParser.ParseTokens(pass, tokens);
                    shader.Passes.Add(pass);
                }
                i += tokens.Count;
            }
            shader.InterfaceManger?.Parse(shader, programChunk.Container);
            if (programChunk.Version.ProgramType == ProgramType.HullShader)
            {
                string patchConstantPassName = "HullPatchConstant";
                shader.Passes.Add(new IrPass("HullPatchConstant", IrPass.PassType.HullShaderPatchConstantPhase));
                var ctrlPointPass = shader.Passes.First(p => p.Type == IrPass.PassType.HullShaderControlPointPhase);
                ctrlPointPass.Attributes.Add(IrAttribute.Create("patchconstantfunc", patchConstantPassName));
            }
        }
Exemple #3
0
        static void ParseLibrary(IrShader shader, BytecodeContainer container)
        {
            var libraryHeader    = container.Chunks.OfType <LibHeaderChunk>().Single();
            var libraryFunctions = container.Chunks.OfType <LibfChunk>().ToArray();

            for (int i = 0; i < libraryFunctions.Length; i++)
            {
                var pass = new IrPass(libraryHeader.FunctionDescs[i].Name, IrPass.PassType.FunctionBody);
                InstructionParser.ParseTokens(pass, libraryFunctions[i].LibraryContainer.Shader.Tokens);
                shader.Passes.Add(pass);
            }
        }
 public void WritePass(IrPass pass)
 {
     foreach (var attribute in pass.Attributes)
     {
         WriteAttribute(attribute);
     }
     WriteIndent();
     WriteLineFormat("void {0}()", pass.Name);
     WriteIndent();
     WriteLine("{");
     IncreaseIndent();
     foreach (var declaration in pass.Declarations)
     {
         WriteDeclrations(declaration);
     }
     foreach (var instruction in pass.Instructions)
     {
         Context.InstructionWriter.WriteInstruction(instruction);
     }
     DecreaseIndent();
     WriteLine("}");
 }
Exemple #5
0
        static void ParseDeclarations(IrPass pass, IEnumerable <DeclarationToken> declarations)
        {
            pass.Declarations = new List <DeclarationToken>(declarations);
            foreach (var token in declarations)
            {
                switch (token.Header.OpcodeType)
                {
                case OpcodeType.DclTessDomain:
                {
                    var decl = token as TessellatorDomainDeclarationToken;
                    pass.Attributes.Add(IrAttribute.Create("domain", decl.Domain.GetAttributeName()));
                }
                break;

                case OpcodeType.DclMaxOutputVertexCount:
                {
                    var decl = token as GeometryShaderMaxOutputVertexCountDeclarationToken;
                    pass.Attributes.Add(IrAttribute.Create("maxvertexcount", decl.MaxPrimitives));
                }
                break;

                case OpcodeType.DclOutputControlPointCount:
                {
                    var decl = token as ControlPointCountDeclarationToken;
                    pass.Attributes.Add(IrAttribute.Create("outputcontrolpoints", decl.ControlPointCount));
                }
                break;

                case OpcodeType.DclTessPartitioning:
                {
                    var decl = token as TessellatorPartitioningDeclarationToken;
                    pass.Attributes.Add(IrAttribute.Create("partitioning", decl.Partitioning.ToString().ToLower()));
                }
                break;

                case OpcodeType.DclHsMaxTessFactor:
                {
                    var decl = token as HullShaderMaxTessFactorDeclarationToken;
                    pass.Attributes.Add(IrAttribute.Create("maxtessfactor", decl.MaxTessFactor));
                }
                break;

                case OpcodeType.DclTessOutputPrimitive:
                {
                    var decl = token as TessellatorOutputPrimitiveDeclarationToken;
                    pass.Attributes.Add(IrAttribute.Create("outputtopology", decl.OutputPrimitive.ToString().ToLower()));
                }
                break;

                case OpcodeType.DclThreadGroup:
                {
                    var decl = token as ThreadGroupDeclarationToken;
                    pass.Attributes.Add(IrAttribute.Create("numthreads",
                                                           decl.Dimensions[0],
                                                           decl.Dimensions[1],
                                                           decl.Dimensions[2]));
                }
                break;
                }
            }
        }
Exemple #6
0
 public static void ParseTokens(IrPass pass, List <OpcodeToken> opcodes)
 {
     ParseDeclarations(pass, opcodes.OfType <DeclarationToken>());
     ParseInstructions(pass, opcodes.OfType <InstructionToken>());
 }