public static InterfaceSlot Parse(BytecodeReader reader, BytecodeReader interfaceSlotReader) { var slotSpan = interfaceSlotReader.ReadUInt32(); var count = interfaceSlotReader.ReadUInt32(); var typeIDsOffset = interfaceSlotReader.ReadUInt32(); var typeIDsReader = reader.CopyAtOffset((int) typeIDsOffset); var tableIDsOffset = interfaceSlotReader.ReadUInt32(); var tableIDsReader = reader.CopyAtOffset((int) tableIDsOffset); var result = new InterfaceSlot { SlotSpan = slotSpan }; for (int i = 0; i < count; i++) { result.TypeIDs.Add(typeIDsReader.ReadUInt16()); result.TableIDs.Add(tableIDsReader.ReadUInt32()); } return result; }
public static ConstantBuffer Parse( BytecodeReader reader, BytecodeReader constantBufferReader, ShaderVersion target) { uint nameOffset = constantBufferReader.ReadUInt32(); var nameReader = reader.CopyAtOffset((int) nameOffset); uint variableCount = constantBufferReader.ReadUInt32(); uint variableOffset = constantBufferReader.ReadUInt32(); var result = new ConstantBuffer { Name = nameReader.ReadString() }; var variableReader = reader.CopyAtOffset((int) variableOffset); for (int i = 0; i < variableCount; i++) result.Variables.Add(ShaderVariable.Parse(reader, variableReader, target, i == 0)); result.Size = constantBufferReader.ReadUInt32(); result.Flags = (ConstantBufferFlags) constantBufferReader.ReadUInt32(); result.BufferType = (ConstantBufferType) constantBufferReader.ReadUInt32(); return result; }
public static ResourceDefinitionChunk Parse(BytecodeReader reader) { var headerReader = reader.CopyAtCurrentPosition(); uint constantBufferCount = headerReader.ReadUInt32(); uint constantBufferOffset = headerReader.ReadUInt32(); uint resourceBindingCount = headerReader.ReadUInt32(); uint resourceBindingOffset = headerReader.ReadUInt32(); var target = ShaderVersion.ParseRdef(headerReader); uint flags = headerReader.ReadUInt32(); var creatorOffset = headerReader.ReadUInt32(); var creatorReader = reader.CopyAtOffset((int) creatorOffset); var creator = creatorReader.ReadString(); var result = new ResourceDefinitionChunk { Target = target, Flags = (ShaderFlags) flags, Creator = creator }; if (target.MajorVersion >= 5) { string rd11 = headerReader.ReadUInt32().ToFourCcString(); if (rd11 != "RD11") throw new ParseException("Expected RD11."); var unknown1 = headerReader.ReadUInt32(); // TODO Debug.Assert(unknown1 == 60); var unknown2 = headerReader.ReadUInt32(); Debug.Assert(unknown2 == 24); var unknown3 = headerReader.ReadUInt32(); Debug.Assert(unknown3 == 32); var unknown4 = headerReader.ReadUInt32(); Debug.Assert(unknown4 == 40); var unknown5 = headerReader.ReadUInt32(); Debug.Assert(unknown5 == 36); var unknown6 = headerReader.ReadUInt32(); Debug.Assert(unknown6 == 12); result.InterfaceSlotCount = headerReader.ReadUInt32(); } var constantBufferReader = reader.CopyAtOffset((int) constantBufferOffset); for (int i = 0; i < constantBufferCount; i++) result.ConstantBuffers.Add(ConstantBuffer.Parse(reader, constantBufferReader, result.Target)); var resourceBindingReader = reader.CopyAtOffset((int) resourceBindingOffset); for (int i = 0; i < resourceBindingCount; i++) result.ResourceBindings.Add(ResourceBinding.Parse(reader, resourceBindingReader)); return result; }
public static InterfacesChunk Parse(BytecodeReader reader, uint sizeInBytes) { var headerReader = reader.CopyAtCurrentPosition(); var result = new InterfacesChunk(); var classInstanceCount = headerReader.ReadUInt32(); var classTypeCount = headerReader.ReadUInt32(); var interfaceSlotRecordCount = headerReader.ReadUInt32(); // Will be same as interfaceSlotRecordCount unless there are interface arrays. result.InterfaceSlotCount = headerReader.ReadUInt32(); headerReader.ReadUInt32(); // Think this is offset to start of interface slot info, but we don't need it. var classTypeOffset = headerReader.ReadUInt32(); var availableClassReader = reader.CopyAtOffset((int) classTypeOffset); var interfaceSlotOffset = headerReader.ReadUInt32(); var interfaceSlotReader = reader.CopyAtOffset((int) interfaceSlotOffset); for (uint i = 0; i < classTypeCount; i++) { var classType = ClassType.Parse(reader, availableClassReader); classType.ID = i; // Really?? result.AvailableClassTypes.Add(classType); } for (uint i = 0; i < classInstanceCount; i++) { var classInstance = ClassInstance.Parse(reader, availableClassReader); result.AvailableClassInstances.Add(classInstance); } uint startSlot = 0; for (uint i = 0; i < interfaceSlotRecordCount; i++) { var interfaceSlot = InterfaceSlot.Parse(reader, interfaceSlotReader); interfaceSlot.StartSlot = startSlot; // Really?? result.InterfaceSlots.Add(interfaceSlot); startSlot += interfaceSlot.SlotSpan; } 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 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() }; }
public static ResourceBinding Parse(BytecodeReader reader, BytecodeReader resourceBindingReader) { uint nameOffset = resourceBindingReader.ReadUInt32(); var nameReader = reader.CopyAtOffset((int) nameOffset); return new ResourceBinding { Name = nameReader.ReadString(), Type = (ShaderInputType) resourceBindingReader.ReadUInt32(), ReturnType = (ResourceReturnType) resourceBindingReader.ReadUInt32(), Dimension = (ShaderResourceViewDimension) resourceBindingReader.ReadUInt32(), NumSamples = resourceBindingReader.ReadUInt32(), BindPoint = resourceBindingReader.ReadUInt32(), BindCount = resourceBindingReader.ReadUInt32(), Flags = (ShaderInputFlags) resourceBindingReader.ReadUInt32() }; }
public BytecodeContainer(byte[] rawBytes) { _rawBytes = rawBytes; Chunks = new List<BytecodeChunk>(); var reader = new BytecodeReader(rawBytes, 0, rawBytes.Length); Header = BytecodeContainerHeader.Parse(reader); for (uint i = 0; i < Header.ChunkCount; i++) { uint chunkOffset = reader.ReadUInt32(); var chunkReader = reader.CopyAtOffset((int)chunkOffset); var chunk = BytecodeChunk.ParseChunk(chunkReader, this); if (chunk != null) Chunks.Add(chunk); } }
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() }; }
///// <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 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; }
public static SignatureParameterDescription Parse(BytecodeReader reader, BytecodeReader parameterReader, ChunkType chunkType, SignatureElementSize size, ProgramType programType) { uint stream = 0; if (size == SignatureElementSize._7) stream = parameterReader.ReadUInt32(); uint nameOffset = parameterReader.ReadUInt32(); var nameReader = reader.CopyAtOffset((int) nameOffset); var result = new SignatureParameterDescription { SemanticName = nameReader.ReadString(), SemanticIndex = parameterReader.ReadUInt32(), SystemValueType = (Name) parameterReader.ReadUInt32(), ComponentType = (RegisterComponentType) parameterReader.ReadUInt32(), Register = parameterReader.ReadUInt32(), Stream = stream, //MinPrecision = (MinPrecision) parameterReader.ReadByte() TODO }; uint mask = parameterReader.ReadUInt32(); result.Mask = mask.DecodeValue<ComponentMask>(0, 7); result.ReadWriteMask = mask.DecodeValue<ComponentMask>(8, 15); // This is my guesswork, but it works so far... if (chunkType == ChunkType.Osg5 || chunkType == ChunkType.Osgn || (chunkType == ChunkType.Pcsg && programType == ProgramType.HullShader)) result.ReadWriteMask = (ComponentMask) (ComponentMask.All - result.ReadWriteMask); // Vertex and pixel shaders need special handling for SystemValueType in the output signature. if ((programType == ProgramType.PixelShader || programType == ProgramType.VertexShader) && (chunkType == ChunkType.Osg5 || chunkType == ChunkType.Osgn)) { if (result.Register == 0xffffffff) switch (result.SemanticName.ToUpper()) { case "SV_DEPTH": result.SystemValueType = Name.Depth; break; case "SV_COVERAGE": result.SystemValueType = Name.Coverage; break; case "SV_DEPTHGREATEREQUAL": result.SystemValueType = Name.DepthGreaterEqual; break; case "SV_DEPTHLESSEQUAL": result.SystemValueType = Name.DepthLessEqual; break; } else if (programType == ProgramType.PixelShader) result.SystemValueType = Name.Target; } return result; }