public static ShaderProgramChunk Parse(BytecodeReader reader) { var program = new ShaderProgramChunk { Version = ShaderVersion.ParseShex(reader), // Length Token (LenTok) // Always follows VerTok // [31:00] Unsigned integer count of number of DWORDs in program code, including version and length tokens. // So the minimum value is 0x00000002 (if an empty program is ever valid). Length = reader.ReadUInt32() }; while (!reader.EndOfBuffer) { // Opcode Format (OpcodeToken0) // // [10:00] D3D10_SB_OPCODE_TYPE // if( [10:00] == D3D10_SB_OPCODE_CUSTOMDATA ) // { // Token starts a custom-data block. See "Custom-Data Block Format". // } // else // standard opcode token // { // [23:11] Opcode-Specific Controls // [30:24] Instruction length in DWORDs including the opcode token. // [31] 0 normally. 1 if extended operand definition, meaning next DWORD // contains extended opcode token. // } var opcodeHeaderReader = reader.CopyAtCurrentPosition(); var opcodeToken0 = opcodeHeaderReader.ReadUInt32(); var opcodeHeader = new OpcodeHeader { OpcodeType = opcodeToken0.DecodeValue<OpcodeType>(0, 10), Length = opcodeToken0.DecodeValue(24, 30), IsExtended = (opcodeToken0.DecodeValue(31, 31) == 1) }; OpcodeToken opcodeToken; if (opcodeHeader.OpcodeType == OpcodeType.CustomData) { opcodeToken = CustomDataToken.Parse(reader, opcodeToken0); } else if (opcodeHeader.OpcodeType.IsDeclaration()) { opcodeToken = DeclarationToken.Parse(reader, opcodeHeader.OpcodeType); } else // Not custom data or declaration, so must be instruction. { opcodeToken = InstructionToken.Parse(reader, opcodeHeader); } opcodeToken.Header = opcodeHeader; program.Tokens.Add(opcodeToken); } program.LinkControlFlowInstructions(); return program; }
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 InputOutputSignatureChunk Parse(BytecodeReader reader, ChunkType chunkType, ProgramType programType) { InputOutputSignatureChunk result; switch (chunkType) { case ChunkType.Isgn : result = new InputSignatureChunk(); break; case ChunkType.Osgn : case ChunkType.Osg5 : result = new OutputSignatureChunk(); break; case ChunkType.Pcsg : result = new PatchConstantSignatureChunk(); break; default : throw new ArgumentOutOfRangeException("chunkType", "Unrecognised chunk type: " + chunkType); } var chunkReader = reader.CopyAtCurrentPosition(); var elementCount = chunkReader.ReadUInt32(); var uniqueKey = chunkReader.ReadUInt32(); SignatureElementSize elementSize; switch (chunkType) { case ChunkType.Osg5 : elementSize = SignatureElementSize._7; break; case ChunkType.Isgn: case ChunkType.Osgn: case ChunkType.Pcsg: elementSize = SignatureElementSize._6; break; default: throw new ArgumentOutOfRangeException("chunkType", "Unrecognised chunk type: " + chunkType); } for (int i = 0; i < elementCount; i++) result.Parameters.Add(SignatureParameterDescription.Parse(reader, chunkReader, chunkType, elementSize, programType)); return result; }
public static BytecodeChunk ParseChunk(BytecodeReader chunkReader, BytecodeContainer container) { // Type of chunk this is. uint fourCc = chunkReader.ReadUInt32(); // Total length of the chunk in bytes. uint chunkSize = chunkReader.ReadUInt32(); ChunkType chunkType; if (KnownChunkTypes.ContainsKey(fourCc)) { chunkType = KnownChunkTypes[fourCc]; } else { System.Diagnostics.Debug.WriteLine("Chunk type '" + fourCc.ToFourCcString() + "' is not yet supported."); return null; } var chunkContentReader = chunkReader.CopyAtCurrentPosition((int) chunkSize); BytecodeChunk chunk; switch (chunkType) { case ChunkType.Ifce : chunk = InterfacesChunk.Parse(chunkContentReader, chunkSize); break; case ChunkType.Isgn : case ChunkType.Osgn: case ChunkType.Osg5: case ChunkType.Pcsg: chunk = InputOutputSignatureChunk.Parse(chunkContentReader, chunkType, container.ResourceDefinition.Target.ProgramType); break; case ChunkType.Rdef: chunk = ResourceDefinitionChunk.Parse(chunkContentReader); break; case ChunkType.Sdbg : case ChunkType.Spdb : chunk = DebuggingChunk.Parse(chunkContentReader, chunkType, (int) chunkSize); break; case ChunkType.Sfi0: chunk = Sfi0Chunk.Parse(chunkContentReader); break; case ChunkType.Shdr: case ChunkType.Shex: chunk = ShaderProgramChunk.Parse(chunkContentReader); break; case ChunkType.Stat: chunk = StatisticsChunk.Parse(chunkContentReader, chunkSize); break; default : throw new ParseException("Invalid chunk type: " + chunkType); } chunk.Container = container; chunk.FourCc = fourCc; chunk.ChunkSize = chunkSize; chunk.ChunkType = chunkType; return chunk; }