/// <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)); } }
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); } }