private void WriteAttribute(IrAttribute attribute) { WriteIndent(); WriteFormat("[{0}(", attribute.Name); Join(", ", attribute.Arguments, (arg) => Write(arg.ToString())); WriteLine(")]"); }
/// <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 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; } } }