///// <summary> ///// Gets the corresponding interface slot for a variable that represents an interface pointer. ///// </summary> //public List<uint> InterfaceSlots { get; private set; } public static ShaderVariable Parse(BytecodeReader reader, BytecodeReader variableReader, ShaderVersion target, bool isFirst) { uint nameOffset = variableReader.ReadUInt32(); var nameReader = reader.CopyAtOffset((int)nameOffset); var startOffset = variableReader.ReadUInt32(); uint size = variableReader.ReadUInt32(); var flags = (ShaderVariableFlags)variableReader.ReadUInt32(); var typeOffset = variableReader.ReadUInt32(); var typeReader = reader.CopyAtOffset((int)typeOffset); var shaderType = ShaderType.Parse(reader, typeReader, target, 2, isFirst, startOffset); var defaultValueOffset = variableReader.ReadUInt32(); List <Number> defaultValue = null; if (defaultValueOffset != 0) { defaultValue = new List <Number>(); var defaultValueReader = reader.CopyAtOffset((int)defaultValueOffset); if (size % 4 != 0) { throw new ParseException("Can only deal with 4-byte default values at the moment."); } for (int i = 0; i < size; i += 4) { defaultValue.Add(new Number(defaultValueReader.ReadBytes(4))); } } var name = nameReader.ReadString(); var result = new ShaderVariable { DefaultValue = defaultValue, Member = new ShaderTypeMember(0) { Name = name, Offset = startOffset, Type = shaderType }, BaseType = name, Size = size, Flags = flags }; if (target.MajorVersion >= 5) { result.StartTexture = variableReader.ReadInt32(); result.TextureSize = variableReader.ReadInt32(); result.StartSampler = variableReader.ReadInt32(); result.SamplerSize = variableReader.ReadInt32(); } return(result); }
public static ShaderTypeMember Parse(BytecodeReader reader, BytecodeReader memberReader, ShaderVersion target, int indent, bool isFirst, uint parentOffset) { var nameOffset = memberReader.ReadUInt32(); var nameReader = reader.CopyAtOffset((int)nameOffset); var name = nameReader.ReadString(); var memberTypeOffset = memberReader.ReadUInt32(); var offset = memberReader.ReadUInt32(); var memberTypeReader = reader.CopyAtOffset((int)memberTypeOffset); var memberType = ShaderType.Parse(reader, memberTypeReader, target, indent, isFirst, parentOffset + offset); return(new ShaderTypeMember(parentOffset) { Name = name, Type = memberType, Offset = offset }); }
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); }