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