public void WriteConstantTable(ConstantTable constantTable) { if (constantTable == null) { return; } WriteLine("//"); WriteLine("// Generated by {0}", constantTable.Creator); if (constantTable.ConstantDeclarations.Count == 0) { return; } WriteLine("//"); WriteLine("// Parameters:"); WriteLine("//"); foreach (var declaration in constantTable.ConstantDeclarations) { string arraySubscript = ""; if (declaration.Elements > 1) { arraySubscript = $"[{declaration.Elements}]"; } WriteLine("// {0} {1}{2};", declaration.GetTypeName(), declaration.Name, arraySubscript ); } WriteLine("//"); WriteLine("//"); WriteLine("// Registers:"); WriteLine("//"); var maxNameLength = constantTable.ConstantDeclarations.Max(cd => cd.Name.Length); if (maxNameLength < 12) { maxNameLength = 12; } WriteLine("// Name{0} Reg Size", new string(' ', maxNameLength - 4)); WriteLine("// {0} ----- ----", new string('-', maxNameLength)); foreach (var declaration in constantTable.ConstantDeclarations .OrderBy(cd => (int)cd.RegisterSet * 1000 + cd.RegisterIndex)) { var size = declaration.Rows * declaration.Columns / 4; if (size == 0) { size = 1; } size = declaration.RegisterCount; WriteLine(string.Format("// {0} {1,-5} {2,4}", declaration.Name.PadRight(maxNameLength, ' '), declaration.GetRegisterName(), size)); } WriteLine("//"); WriteLine(""); }
internal ConstantTable ParseConstantTable() { var constantDeclarations = new List <ConstantDeclaration>(); byte[] constantTable = GetConstantTableData(); if (constantTable == null) { return(null); } var ctabStream = new MemoryStream(constantTable); using (var ctabReader = new BinaryReader(ctabStream)) { int ctabSize = ctabReader.ReadInt32(); System.Diagnostics.Debug.Assert(ctabSize == 0x1C); long creatorPosition = ctabReader.ReadInt32(); int minorVersion = ctabReader.ReadByte(); int majorVersion = ctabReader.ReadByte(); System.Diagnostics.Debug.Assert(majorVersion == MajorVersion); System.Diagnostics.Debug.Assert(minorVersion == MinorVersion); var shaderType = (ShaderType)ctabReader.ReadUInt16(); System.Diagnostics.Debug.Assert(shaderType == Type); int numConstants = ctabReader.ReadInt32(); long constantInfoPosition = ctabReader.ReadInt32(); ShaderFlags shaderFlags = (ShaderFlags)ctabReader.ReadInt32(); long shaderModelPosition = ctabReader.ReadInt32(); //Console.WriteLine("ctabStart = {0}, shaderModelPosition = {1}", ctabStart, shaderModelPosition); ctabStream.Position = creatorPosition; string compilerInfo = ReadStringNullTerminated(ctabStream); ctabStream.Position = shaderModelPosition; string shaderModel = ReadStringNullTerminated(ctabStream); for (int i = 0; i < numConstants; i++) { ctabStream.Position = constantInfoPosition + i * 20; ConstantDeclaration declaration = ReadConstantDeclaration(ctabReader); constantDeclarations.Add(declaration); } var ct = new ConstantTable(compilerInfo, shaderModel, majorVersion, minorVersion, constantDeclarations); ConstantTable = ct; return(ConstantTable); } }
Token ReadInstruction(BytecodeReader reader) { uint instructionToken = reader.ReadUInt32(); Opcode opcode = (Opcode)(instructionToken & 0xffff); int size; if (opcode == Opcode.Comment) { size = (int)((instructionToken >> 16) & 0x7FFF); } else { size = (int)((instructionToken >> 24) & 0x0f); } Token token = null; if (opcode == Opcode.Comment) { var fourCC = reader.ReadUInt32(); if (KnownCommentTypes.ContainsKey(fourCC)) { var commentReader = reader.CopyAtCurrentPosition(); reader.ReadBytes(size * 4 - 4); switch (KnownCommentTypes[fourCC]) { case CommentType.CTAB: ConstantTable = ConstantTable.Parse(commentReader); return(null); case CommentType.C**T: Cli = CliToken.Parse(commentReader); return(null); case CommentType.FXLC: Fxlc = FxlcBlock.Parse(commentReader); return(null); case CommentType.PRES: Preshader = Preshader.Parse(commentReader); return(null); case CommentType.PRSI: Prsi = PrsiToken.Parse(commentReader); return(null); } } token = new CommentToken(opcode, size, this); token.Data[0] = fourCC; for (int i = 1; i < size; i++) { token.Data[i] = reader.ReadUInt32(); } } else { token = new InstructionToken(opcode, size, this); var inst = token as InstructionToken; for (int i = 0; i < size; i++) { token.Data[i] = reader.ReadUInt32(); if (opcode == Opcode.Def || opcode == Opcode.DefB || opcode == Opcode.DefI) { } else if (opcode == Opcode.Dcl) { if (i == 0) { inst.Operands.Add(new DeclarationOperand(token.Data[i])); } else { inst.Operands.Add(new DestinationOperand(token.Data[i])); } } else if (i == 0 && opcode != Opcode.BreakC && opcode != Opcode.IfC && opcode != Opcode.If) { inst.Operands.Add(new DestinationOperand(token.Data[i])); } else if ((token.Data[i] & (1 << 13)) != 0) { //Relative Address mode token.Data[i + 1] = reader.ReadUInt32(); inst.Operands.Add(new SourceOperand(token.Data[i], token.Data[i + 1])); i++; } else { inst.Operands.Add(new SourceOperand(token.Data[i])); } } if (opcode != Opcode.Comment) { token.Modifier = (int)((instructionToken >> 16) & 0xff); token.Predicated = (instructionToken & 0x10000000) != 0; token.CoIssue = (instructionToken & 0x40000000) != 0; Debug.Assert((instructionToken & 0xA0000000) == 0, $"Instruction has unexpected bits set {instructionToken & 0xE0000000}"); } } return(token); }
public AsmWriter(ShaderModel shader) { this.shader = shader; constantTable = shader.ParseConstantTable(); }