Ejemplo n.º 1
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));
            }
        }
Ejemplo n.º 2
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);
            }
        }