public static ConstantDeclaration Parse(BytecodeReader reader, BytecodeReader decReader) { var result = new ConstantDeclaration(); var nameOffset = decReader.ReadUInt32(); result.RegisterSet = (RegisterSet)decReader.ReadUInt16(); result.RegisterIndex = decReader.ReadUInt16(); result.RegisterCount = decReader.ReadUInt16(); decReader.ReadUInt16(); //Reserved var typeInfoOffset = decReader.ReadUInt32(); var defaultValueOffset = decReader.ReadUInt32(); var nameReader = reader.CopyAtOffset((int)nameOffset); result.Name = nameReader.ReadString(); var typeReader = reader.CopyAtOffset((int)typeInfoOffset); result.Type = ConstantType.Parse(reader, typeReader); var memberInfoOffset = typeReader.ReadUInt32(); if (defaultValueOffset != 0) { //Note: thre are corrisponding def instructions. TODO: check that they are the same var defaultValueReader = reader.CopyAtOffset((int)defaultValueOffset); for (int i = 0; i < 4; i++) { result.DefaultValue.Add(defaultValueReader.ReadSingle()); } } return(result); }
public static DebugNameChunk Parse(BytecodeReader reader, uint chunkSize) { var result = new DebugNameChunk(); var flags = reader.ReadUInt16(); var nameLength = reader.ReadUInt16(); result.Name = reader.ReadString(); return(result); }
public static LoopRegisterMapping Parse(BytecodeReader reader) { var result = new LoopRegisterMapping(); result.Buffer = reader.ReadUInt16(); result.SourceReg = reader.ReadUInt16(); result.Component = reader.ReadUInt16(); result.TargetReg = reader.ReadUInt16(); return(result); }
public static MSInfo Parse(BytecodeReader reader) { return(new MSInfo() { GroupSharedBytesUsed = reader.ReadUInt32(), GroupSharedBytesDependentOnViewID = reader.ReadUInt32(), PayloadSizeInBytes = reader.ReadUInt32(), MaxOutputVertices = reader.ReadUInt16(), MaxOutputPrimitives = reader.ReadUInt16(), }); }
public static RuntimeConstantMapping Parse(BytecodeReader reader) { var result = new RuntimeConstantMapping(); result.ConstantDescription = (RuntimeConstantDescription)reader.ReadUInt16(); result.TargetReg = reader.ReadUInt16(); Debug.Assert( Enum.IsDefined(typeof(RuntimeConstantDescription), result.ConstantDescription), $"Unknown RuntimeConstantDescription {result.ConstantDescription}"); return(result); }
public static ClassType Parse(BytecodeReader reader, BytecodeReader classTypeReader) { var nameOffset = classTypeReader.ReadUInt32(); var nameReader = reader.CopyAtOffset((int)nameOffset); return(new ClassType { Name = nameReader.ReadString(), ID = classTypeReader.ReadUInt16(), ConstantBufferStride = classTypeReader.ReadUInt16(), Texture = classTypeReader.ReadUInt16(), Sampler = classTypeReader.ReadUInt16() }); }
/* * There are a few token types: * comment_token fourCC data * def_token dest_param literal_param literal_param literal_param literal_param * dcl_token decl_param dest_param * inst_token dest_param [src_param ...] * end_token */ public static ShaderModel Parse(BytecodeReader reader) { var result = new ShaderModel(); result.MinorVersion = reader.ReadByte(); result.MajorVersion = reader.ReadByte(); result.Type = (ShaderType)reader.ReadUInt16(); //SM1 shaders do not encode instruction size which rely on for reading operands. //So we won't support SM1 if (result.MajorVersion == 1) { throw new ParseException("Shader Model 1 is not supported"); } while (true) { var instruction = result.ReadInstruction(reader); if (instruction == null) { continue; } result.Tokens.Add(instruction); if (instruction.Opcode == Opcode.End) { break; } } return(result); }
public static ConstantTable Parse(BytecodeReader ctabReader) { var result = new ConstantTable(); var ctabSize = ctabReader.ReadUInt32(); var creatorOffset = ctabReader.ReadInt32(); result.MajorVersion = ctabReader.ReadByte(); result.MinorVersion = ctabReader.ReadByte(); var shaderType = (ShaderType)ctabReader.ReadUInt16(); var numConstants = ctabReader.ReadInt32(); var constantInfoOffset = ctabReader.ReadInt32(); var shaderFlags = (ShaderFlags)ctabReader.ReadUInt32(); var shaderModelOffset = ctabReader.ReadInt32(); for (int i = 0; i < numConstants; i++) { var decReader = ctabReader.CopyAtOffset(constantInfoOffset + i * 20); ConstantDeclaration declaration = ConstantDeclaration.Parse(ctabReader, decReader); result.ConstantDeclarations.Add(declaration); } var shaderModelReader = ctabReader.CopyAtOffset(shaderModelOffset); result.VersionString = shaderModelReader.ReadString(); var creatorReader = ctabReader.CopyAtOffset(creatorOffset); result.Creator = creatorReader.ReadString(); return(result); }
public static ConstantBufferMapping Parse(BytecodeReader reader) { var result = new ConstantBufferMapping(); result.Buffer = reader.ReadUInt16(); result.StartReg = reader.ReadUInt16(); result.RegCount = reader.ReadUInt16(); result.TargetReg = reader.ReadUInt16(); for (int i = 0; i < 4; i++) { var type = (DataConversionType)reader.ReadByte(); result.DataConversion[i] = type; Debug.Assert(Enum.IsDefined(typeof(DataConversionType), type), $"Invalid DataConversionType {type}"); } return(result); }
public static ShaderVersion ParseFX(BytecodeReader reader) { uint target = reader.ReadUInt16(); var programTypeValue = reader.ReadUInt16(); ProgramType programType = ParseRdefProgramType(programTypeValue); byte majorVersion; byte minorVersion; switch (target) { case 0x1001: majorVersion = 4; minorVersion = 0; break; case 0x1011: majorVersion = 4; minorVersion = 1; break; case 0x2001: majorVersion = 5; minorVersion = 0; break; case 0x0901: majorVersion = 2; minorVersion = 0; break; default: throw new ParseException(string.Format("Unknown program version: 0x{0:X}", target)); } return(new ShaderVersion { MajorVersion = majorVersion, MinorVersion = minorVersion, ProgramType = programType }); }
public static ShaderVersion ParseAon9(BytecodeReader reader) { byte minor = reader.ReadByte(); byte major = reader.ReadByte(); ushort shaderType = reader.ReadUInt16(); return(new ShaderVersion { MinorVersion = minor, MajorVersion = major, ProgramType = shaderType == 0xFFFF ? ProgramType.PixelShader : ProgramType.VertexShader }); }
public static ShaderModel Parse(BytecodeReader reader) { var result = new ShaderModel(); result.MinorVersion = reader.ReadByte(); result.MajorVersion = reader.ReadByte(); result.Type = (ShaderType)reader.ReadUInt16(); while (true) { var instruction = result.ReadInstruction(reader); if (instruction == null) { continue; } result.Tokens.Add(instruction); if (instruction.Opcode == Opcode.End) { break; } } return(result); }
public static ClassInstance Parse(BytecodeReader reader, BytecodeReader classInstanceReader) { var nameOffset = classInstanceReader.ReadUInt32(); var nameReader = reader.CopyAtOffset((int)nameOffset); var name = nameReader.ReadString(); return(new ClassInstance { Name = name, Type = classInstanceReader.ReadUInt16(), ElementCount = classInstanceReader.ReadUInt16(), ConstantBuffer = classInstanceReader.ReadUInt16(), ConstantBufferOffset = classInstanceReader.ReadUInt16(), Texture = classInstanceReader.ReadUInt16(), Sampler = classInstanceReader.ReadUInt16(), }); }
public static ClassInstance Parse(BytecodeReader reader, BytecodeReader classInstanceReader) { var nameOffset = classInstanceReader.ReadUInt32(); var nameReader = reader.CopyAtOffset((int)nameOffset); var name = nameReader.ReadString(); var type = classInstanceReader.ReadUInt16(); var unknown = classInstanceReader.ReadUInt16(); Debug.Assert(unknown == 1); // Unknown, perhaps the class instance type? return(new ClassInstance { Name = name, Type = type, ConstantBuffer = classInstanceReader.ReadUInt16(), ConstantBufferOffset = classInstanceReader.ReadUInt16(), Texture = classInstanceReader.ReadUInt16(), Sampler = classInstanceReader.ReadUInt16() }); }
public static ConstantType Parse(BytecodeReader reader, BytecodeReader typeReader) { var result = new ConstantType(); result.ParameterClass = (ParameterClass)typeReader.ReadUInt16(); result.ParameterType = (ParameterType)typeReader.ReadUInt16(); result.Rows = typeReader.ReadUInt16(); result.Columns = typeReader.ReadUInt16(); result.Elements = typeReader.ReadUInt16(); var memberCount = typeReader.ReadUInt16(); var memberInfoOffset = typeReader.ReadUInt32(); if (memberCount != 0) { var memberReader = reader.CopyAtOffset((int)memberInfoOffset); for (int i = 0; i < memberCount; i++) { result.Members.Add(ConstantMember.Parse(reader, memberReader)); } } return(result); }
public static ShaderType Parse(BytecodeReader reader, BytecodeReader typeReader, ShaderVersion target, int indent, bool isFirst, uint parentOffset) { var result = new ShaderType(indent, isFirst) { VariableClass = (ShaderVariableClass)typeReader.ReadUInt16(), VariableType = (ShaderVariableType)typeReader.ReadUInt16(), Rows = typeReader.ReadUInt16(), Columns = typeReader.ReadUInt16(), ElementCount = typeReader.ReadUInt16() }; var memberCount = typeReader.ReadUInt16(); var memberOffset = typeReader.ReadUInt32(); if (target.MajorVersion >= 5) { var subTypeOffset = typeReader.ReadUInt32(); // Guessing if (subTypeOffset != 0) { var parentTypeReader = reader.CopyAtOffset((int)subTypeOffset); result.SubType = ShaderType.Parse(reader, parentTypeReader, target, indent + 4, true, parentOffset); Debug.Assert( result.SubType.VariableClass == ShaderVariableClass.Vector || result.SubType.VariableClass == ShaderVariableClass.InterfaceClass); } var baseClassOffset = typeReader.ReadUInt32(); if (baseClassOffset != 0) { var baseClassReader = reader.CopyAtOffset((int)baseClassOffset); result.BaseClass = ShaderType.Parse(reader, baseClassReader, target, indent + 4, true, parentOffset); Debug.Assert( result.BaseClass.VariableClass == ShaderVariableClass.Scalar || result.BaseClass.VariableClass == ShaderVariableClass.Struct); } var interfaceCount = typeReader.ReadUInt32(); var interfaceSectionOffset = typeReader.ReadUInt32(); if (interfaceSectionOffset != 0) { var interfaceSectionReader = reader.CopyAtOffset((int)interfaceSectionOffset); for (int i = 0; i < interfaceCount; i++) { var interfaceTypeOffset = interfaceSectionReader.ReadUInt32(); var interfaceReader = reader.CopyAtOffset((int)interfaceTypeOffset); result.Interfaces.Add(ShaderType.Parse(reader, interfaceReader, target, indent + 4, i == 0, parentOffset)); } } var parentNameOffset = typeReader.ReadUInt32(); if (parentNameOffset > 0) { var parentNameReader = reader.CopyAtOffset((int)parentNameOffset); result.BaseTypeName = parentNameReader.ReadString(); } } if (memberCount > 0) { var memberReader = reader.CopyAtOffset((int)memberOffset); for (int i = 0; i < memberCount; i++) { result.Members.Add(ShaderTypeMember.Parse(reader, memberReader, target, indent + 4, i == 0, parentOffset)); } } if (target.ProgramType == ProgramType.LibraryShader && target.MajorVersion == 4) { var unk1 = typeReader.ReadUInt32(); var unk2 = typeReader.ReadUInt32(); var unk3 = typeReader.ReadUInt32(); var unk4 = typeReader.ReadUInt32(); var typeNameOffset = typeReader.ReadUInt32(); var typeNameReader = reader.CopyAtOffset((int)typeNameOffset); typeNameReader.ReadString(); Debug.Assert(unk1 == 0, $"ShaderType.Unk1={unk1}"); Debug.Assert(unk2 == 0, $"ShaderType.Unk2={unk2}"); Debug.Assert(unk3 == 0, $"ShaderType.Unk3={unk3}"); Debug.Assert(unk4 == 0, $"ShaderType.Unk4={unk4}"); } return(result); }
internal static BytecodeChunk Parse(BytecodeReader chunkContentReader, uint chunkSize) { var result = new Level9ShaderChunk(); uint chunkSize2 = chunkContentReader.ReadUInt32(); result.Version = ShaderVersion.ParseAon9(chunkContentReader); uint shaderSize = chunkContentReader.ReadUInt32(); var shaderOffset = chunkContentReader.ReadUInt32(); var cbMappingCount = chunkContentReader.ReadUInt16(); var cbMappingOffset = chunkContentReader.ReadUInt16(); var loopRegisterMappingCount = chunkContentReader.ReadUInt16(); var loopRegisterMappingOffset = chunkContentReader.ReadUInt16(); var unk0MappingCount = chunkContentReader.ReadUInt16(); var unk0MappingOffset = chunkContentReader.ReadUInt16(); var samplerMappingCount = chunkContentReader.ReadUInt16(); var samplerMappingOffset = chunkContentReader.ReadUInt16(); var runtimeConstantMappingCount = chunkContentReader.ReadUInt16(); var runtimeConstantMappingOffset = chunkContentReader.ReadUInt16(); if (cbMappingCount > 0) { var mappingReader = chunkContentReader.CopyAtOffset(cbMappingOffset); for (int i = 0; i < cbMappingCount; i++) { result.ConstantBufferMappings.Add(ConstantBufferMapping.Parse(mappingReader)); } } if (loopRegisterMappingCount > 0) { var mappingReader = chunkContentReader.CopyAtOffset(loopRegisterMappingOffset); for (int i = 0; i < loopRegisterMappingCount; i++) { result.LoopRegisterMappings.Add(LoopRegisterMapping.Parse(mappingReader)); } } if (unk0MappingCount > 0) { Debug.Assert(false, "Unknown Level9 Mapping"); var mappingReader = chunkContentReader.CopyAtOffset(unk0MappingOffset); for (int i = 0; i < unk0MappingCount; i++) { result.Unknown0Mappings.Add(Unknown1Mapping.Parse(mappingReader)); } } if (samplerMappingCount > 0) { var mappingReader = chunkContentReader.CopyAtOffset(samplerMappingOffset); for (int i = 0; i < samplerMappingCount; i++) { result.SamplerMappings.Add(SamplerMapping.Parse(mappingReader)); } // FXC dissassembly sorts sampler mappings result.SamplerMappings = result.SamplerMappings .OrderBy(s => s.TargetSampler) .ToList(); } if (runtimeConstantMappingCount > 0) { var mappingReader = chunkContentReader.CopyAtOffset(runtimeConstantMappingOffset); for (int i = 0; i < runtimeConstantMappingCount; i++) { result.RuntimeConstantMappings.Add(RuntimeConstantMapping.Parse(mappingReader)); } } var shaderChunkReader = chunkContentReader.CopyAtOffset((int)shaderOffset); var byteCode = shaderChunkReader.ReadBytes((int)shaderSize); using (var memoryStream = new MemoryStream(byteCode)) { result.ShaderModel = DX9Shader.ShaderReader.ReadShader(memoryStream); } return(result); }
public static ShaderType Parse(BytecodeReader reader, BytecodeReader typeReader, ShaderVersion target, int indent, bool isFirst, uint parentOffset) { var result = new ShaderType(indent, isFirst) { VariableClass = (ShaderVariableClass)typeReader.ReadUInt16(), VariableType = (ShaderVariableType)typeReader.ReadUInt16(), Rows = typeReader.ReadUInt16(), Columns = typeReader.ReadUInt16(), ElementCount = typeReader.ReadUInt16() }; var memberCount = typeReader.ReadUInt16(); var memberOffset = typeReader.ReadUInt32(); if (target.MajorVersion >= 5) { var parentTypeOffset = typeReader.ReadUInt32(); // Guessing if (parentTypeOffset != 0) { var parentTypeReader = reader.CopyAtOffset((int)parentTypeOffset); var parentTypeClass = (ShaderVariableClass)parentTypeReader.ReadUInt16(); Debug.Assert(parentTypeClass == ShaderVariableClass.Vector || parentTypeClass == ShaderVariableClass.InterfaceClass); var unknown1 = parentTypeReader.ReadUInt16(); Debug.Assert(unknown1 == 0); } var unknown2 = typeReader.ReadUInt32(); if (unknown2 != 0) { var unknownReader = reader.CopyAtOffset((int)unknown2); uint unknown3 = unknownReader.ReadUInt32(); Debug.Assert(unknown3 == 0 || unknown3 == 5); } var unknown4 = typeReader.ReadUInt32(); Debug.Assert(unknown4 == 0 || unknown4 == 1); var unknown5 = typeReader.ReadUInt32(); if (unknown5 != 0) { var unknownReader = reader.CopyAtOffset((int)unknown5); var unknown6 = unknownReader.ReadUInt32(); Debug.Assert(unknown6 == 580 || unknown6 == 740); } var parentNameOffset = typeReader.ReadUInt32(); if (parentNameOffset > 0) { var parentNameReader = reader.CopyAtOffset((int)parentNameOffset); result.BaseTypeName = parentNameReader.ReadString(); } } if (memberCount > 0) { var memberReader = reader.CopyAtOffset((int)memberOffset); for (int i = 0; i < memberCount; i++) { result.Members.Add(ShaderTypeMember.Parse(reader, memberReader, target, indent + 4, i == 0, parentOffset)); } } return(result); }