shared_ptr<HullShaderForkPhaseInstanceCountDeclarationToken> HullShaderForkPhaseInstanceCountDeclarationToken::Parse(BytecodeReader& reader) { auto token0 = reader.ReadUInt32(); auto result = shared_ptr<HullShaderForkPhaseInstanceCountDeclarationToken>(new HullShaderForkPhaseInstanceCountDeclarationToken()); result->_instanceCount = reader.ReadUInt32(); return result; }
shared_ptr<TempRegisterDeclarationToken> TempRegisterDeclarationToken::Parse(BytecodeReader& reader) { auto token0 = reader.ReadUInt32(); auto result = shared_ptr<TempRegisterDeclarationToken>(new TempRegisterDeclarationToken()); result->_tempCount = reader.ReadUInt32(); return result; };
shared_ptr<IndexingRangeDeclarationToken> IndexingRangeDeclarationToken::Parse(BytecodeReader& reader) { auto token0 = reader.ReadUInt32(); auto operand = Operand::Parse(reader, DecodeValue<OpcodeType>(token0, 0, 10)); auto result = shared_ptr<IndexingRangeDeclarationToken>(new IndexingRangeDeclarationToken(operand)); result->_registerCount = reader.ReadUInt32(); return result; }
shared_ptr<RawThreadGroupSharedMemoryDeclarationToken> RawThreadGroupSharedMemoryDeclarationToken::Parse(BytecodeReader& reader) { auto token0 = reader.ReadUInt32(); auto operand = Operand::Parse(reader, DecodeValue<OpcodeType>(token0, 0, 10)); auto result = shared_ptr<RawThreadGroupSharedMemoryDeclarationToken>(new RawThreadGroupSharedMemoryDeclarationToken(operand)); result->_elementCount = reader.ReadUInt32(); return result; }
shared_ptr<ThreadGroupDeclarationToken> ThreadGroupDeclarationToken::Parse(BytecodeReader& reader) { auto token0 = reader.ReadUInt32(); auto result = shared_ptr<ThreadGroupDeclarationToken>(new ThreadGroupDeclarationToken()); result->_dimensions[0] = reader.ReadUInt32(); result->_dimensions[1] = reader.ReadUInt32(); result->_dimensions[2] = reader.ReadUInt32(); return result; };
shared_ptr<StructuredUnorderedAccessViewDeclarationToken> StructuredUnorderedAccessViewDeclarationToken::Parse(BytecodeReader& reader) { auto token0 = reader.ReadUInt32(); auto coherency = DecodeValue<UnorderedAccessViewCoherency>(token0, 16, 16); auto operand = Operand::Parse(reader, DecodeValue<OpcodeType>(token0, 0, 10)); auto result = shared_ptr<StructuredUnorderedAccessViewDeclarationToken>(new StructuredUnorderedAccessViewDeclarationToken(coherency, operand)); result->_hasOrderPreservingCounter = (DecodeValue(token0, 23, 23) == 0), result->_byteStride = reader.ReadUInt32(); return result; }
shared_ptr<DxbcChunk> DxbcChunk::Parse(BytecodeReader& chunkReader, const DxbcContainer& container) { // Type of chunk this is. auto fourCc = chunkReader.ReadUInt32(); // Total length of the chunk in bytes. auto chunkSize = chunkReader.ReadUInt32(); ChunkType chunkType = static_cast<ChunkType>(fourCc); BytecodeReader chunkContentReader(chunkReader, chunkSize); shared_ptr<DxbcChunk> chunk; switch (chunkType) { case ChunkType::Ifce : chunk = InterfacesChunk::Parse(chunkContentReader, chunkSize); break; case ChunkType::Isgn : case ChunkType::Osgn: //case ChunkType::Osg5: // Doesn't seem to be used? case ChunkType::Pcsg: chunk = InputOutputSignatureChunk::Parse(chunkContentReader, chunkType, container.GetResourceDefinition()->GetTarget().GetProgramType()); break; case ChunkType::Rdef: chunk = ResourceDefinitionChunk::Parse(chunkContentReader); break; case ChunkType::Sdbg : chunk = DebuggingChunk::Parse(chunkContentReader); 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; case ChunkType::Spdb: // Visual Studio Debug Chunk // No Parse chunk = ShaderPassDebugChunk::Parse(chunkContentReader, chunkSize); break; default : throw std::runtime_error("Chunk type '" + ToFourCcString(fourCc) + "' is not yet supported."); } chunk->_fourCc = fourCc; chunk->_chunkSize = chunkSize; chunk->_chunkType = chunkType; return chunk; }
shared_ptr<GeometryShaderOutputPrimitiveTopologyDeclarationToken> GeometryShaderOutputPrimitiveTopologyDeclarationToken::Parse(BytecodeReader& reader) { auto token0 = reader.ReadUInt32(); auto result = shared_ptr<GeometryShaderOutputPrimitiveTopologyDeclarationToken>(new GeometryShaderOutputPrimitiveTopologyDeclarationToken()); result->_primitiveTopology = DecodeValue<PrimitiveTopology>(token0, 11, 17); return result; }
shared_ptr<ControlPointCountDeclarationToken> ControlPointCountDeclarationToken::Parse(BytecodeReader& reader) { auto token0 = reader.ReadUInt32(); auto result = shared_ptr<ControlPointCountDeclarationToken>(new ControlPointCountDeclarationToken()); result->_controlPointCount = DecodeValue(token0, 11, 16); return result; };
shared_ptr<TessellatorDomainDeclarationToken> TessellatorDomainDeclarationToken::Parse(BytecodeReader& reader) { auto token0 = reader.ReadUInt32(); auto result = shared_ptr<TessellatorDomainDeclarationToken>(new TessellatorDomainDeclarationToken()); result->_domain = DecodeValue<TessellatorDomain>(token0, 11, 12); return result; };
shared_ptr<RawUnorderedAccessViewDeclarationToken> RawUnorderedAccessViewDeclarationToken::Parse(BytecodeReader& reader) { auto token0 = reader.ReadUInt32(); auto coherency = DecodeValue<UnorderedAccessViewCoherency>(token0, 16, 16); auto operand = Operand::Parse(reader, DecodeValue<OpcodeType>(token0, 0, 10)); auto result = shared_ptr<RawUnorderedAccessViewDeclarationToken>(new RawUnorderedAccessViewDeclarationToken(coherency, operand)); return result; }
Number Number::Parse(BytecodeReader& reader, NumberType type) { const int byteCount = 4; uint8_t bytes[byteCount]; for (int i = 0; i < byteCount; i++) bytes[i] = reader.ReadUInt8(); return FromRawBytes(bytes, type); }
shared_ptr<ResourceDefinitionChunk> ResourceDefinitionChunk::Parse(BytecodeReader& reader) { BytecodeReader headerReader(reader); auto constantBufferCount = headerReader.ReadUInt32(); auto constantBufferOffset = headerReader.ReadUInt32(); auto resourceBindingCount = headerReader.ReadUInt32(); auto resourceBindingOffset = headerReader.ReadUInt32(); auto target = ShaderVersion::ParseRdef(headerReader); auto flags = static_cast<ShaderFlags>(headerReader.ReadUInt32()); auto creatorOffset = headerReader.ReadUInt32(); auto creatorReader = reader.CopyAtOffset(creatorOffset); auto creator = creatorReader.ReadString(); // TODO: Parse Direct3D 11 resource definition stuff. // https://github.com/mirrors/wine/blob/master/dlls/d3dcompiler_43/reflection.c#L1429 if (target.GetMajorVersion() >= 5) { auto rd11 = ToFourCcString(headerReader.ReadUInt32()); if (rd11 != "RD11") throw runtime_error("Expected RD11."); auto unknown1 = headerReader.ReadUInt32(); auto unknown2 = headerReader.ReadUInt32(); auto unknown3 = headerReader.ReadUInt32(); auto unknown4 = headerReader.ReadUInt32(); auto unknown5 = headerReader.ReadUInt32(); auto unknown6 = headerReader.ReadUInt32(); auto unknown7 = headerReader.ReadUInt32(); } auto result = shared_ptr<ResourceDefinitionChunk>(new ResourceDefinitionChunk(target)); result->_flags = flags; result->_creator = creator; auto constantBufferReader = reader.CopyAtOffset(constantBufferOffset); for (uint32_t i = 0; i < constantBufferCount; i++) result->_constantBuffers.push_back(ConstantBuffer::Parse(reader, constantBufferReader, result->_target)); auto resourceBindingReader = reader.CopyAtOffset(resourceBindingOffset); for (uint32_t i = 0; i < resourceBindingCount; i++) result->_resourceBindings.push_back(ResourceBinding::Parse(reader, resourceBindingReader)); return result; }
shared_ptr<InterfacesChunk> InterfacesChunk::Parse(BytecodeReader& reader, uint32_t sizeInBytes) { BytecodeReader headerReader(reader); auto result = shared_ptr<InterfacesChunk>(new InterfacesChunk()); auto classInstanceCount = headerReader.ReadUInt32(); auto classTypeCount = headerReader.ReadUInt32(); auto 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. auto classTypeOffset = headerReader.ReadUInt32(); auto availableClassReader = reader.CopyAtOffset(classTypeOffset); auto interfaceSlotOffset = headerReader.ReadUInt32(); auto interfaceSlotReader = reader.CopyAtOffset(interfaceSlotOffset); for (uint32_t i = 0; i < classTypeCount; i++) { auto classType = ClassType::Parse(reader, availableClassReader); classType.SetID(i); // TODO: Really?? result->_availableClassTypes.push_back(classType); } for (uint32_t i = 0; i < classInstanceCount; i++) { auto classInstance = ClassInstance::Parse(reader, availableClassReader); result->_availableClassInstances.push_back(classInstance); } uint32_t startSlot = 0; for (uint32_t i = 0; i < interfaceSlotRecordCount; i++) { auto interfaceSlot = InterfaceSlot::Parse(reader, interfaceSlotReader); interfaceSlot.SetStartSlot(startSlot); // TODO: Really?? result->_interfaceSlots.push_back(interfaceSlot); startSlot += interfaceSlot.GetSlotSpan(); } return result; }
DxbcContainer DxbcContainer::Parse(BytecodeReader& reader) { DxbcContainer container; BytecodeReader headerReader(reader); container._header = DxbcContainerHeader::Parse(headerReader); for (uint32_t i = 0; i < container._header.GetChunkCount(); i++) { auto chunkOffset = headerReader.ReadUInt32(); auto chunkReader = reader.CopyAtOffset(chunkOffset); container._chunks.push_back(DxbcChunk::Parse(chunkReader, container)); } return container; }
ResourceBinding ResourceBinding::Parse(const BytecodeReader& reader, BytecodeReader& resourceBindingReader) { auto nameOffset = resourceBindingReader.ReadUInt32(); auto nameReader = reader.CopyAtOffset(nameOffset); ResourceBinding result; result._name = nameReader.ReadString(); result._type = static_cast<ShaderInputType>(resourceBindingReader.ReadUInt32()); result._returnType = static_cast<ResourceReturnType>(resourceBindingReader.ReadUInt32()); result._dimension = static_cast<ShaderResourceViewDimension>(resourceBindingReader.ReadUInt32()); result._numSamples = resourceBindingReader.ReadUInt32(); result._bindPoint = resourceBindingReader.ReadUInt32(); result._bindCount = resourceBindingReader.ReadUInt32(); result._flags = static_cast<ShaderInputFlags>(resourceBindingReader.ReadUInt32()); return result; }
ClassInstance ClassInstance::Parse(const BytecodeReader& reader, BytecodeReader& classInstanceReader) { auto nameOffset = classInstanceReader.ReadUInt32(); auto nameReader = reader.CopyAtOffset(nameOffset); auto name = nameReader.ReadString(); auto type = classInstanceReader.ReadUInt16(); auto unknown = classInstanceReader.ReadUInt16(); assert(unknown == 1); // Unknown, perhaps the class instance type? ClassInstance result; result._name = name; result._type = type; result._constantBuffer = classInstanceReader.ReadUInt16(); result._constantBufferOffset = classInstanceReader.ReadUInt16(); result._texture = classInstanceReader.ReadUInt16(); result._sampler = classInstanceReader.ReadUInt16(); return result; }
shared_ptr<Sfi0Chunk> Sfi0Chunk::Parse(BytecodeReader& reader) { auto unknown = reader.ReadInt32(); assert(unknown == 2); // TODO: Unknown return shared_ptr<Sfi0Chunk>(new Sfi0Chunk()); }
SystemValueName NameToken::Parse(BytecodeReader& reader) { auto token = reader.ReadUInt32(); return DecodeValue<SystemValueName>(token, 0, 15); }
shared_ptr<InstructionToken> InstructionToken::Parse(BytecodeReader& reader, const OpcodeHeader& header) { auto instructionToken = shared_ptr<InstructionToken>(new InstructionToken()); // Advance to next token. auto instructionEnd = reader.GetCurrentPosition() + (header.Length * sizeof(uint32_t)); auto token0 = reader.ReadUInt32(); if (header.OpcodeType == OpcodeType::Sync) { instructionToken->_syncFlags = DecodeValue<SyncFlags>(token0, 11, 14); } else { instructionToken->_saturate = (DecodeValue(token0, 13, 13) == 1); instructionToken->_testBoolean = DecodeValue<InstructionTestBoolean>(token0, 18, 18); } bool extended = header.IsExtended; while (extended) { auto extendedToken = reader.ReadUInt32(); auto extendedType = DecodeValue<InstructionTokenExtendedType>(extendedToken, 0, 5); instructionToken->_extendedTypes.push_back(extendedType); extended = (DecodeValue(extendedToken, 31, 31) == 1); switch (extendedType) { case InstructionTokenExtendedType::SampleControls: instructionToken->_sampleOffsets[0] = DecodeSigned4BitValue(extendedToken, 9, 12); instructionToken->_sampleOffsets[1] = DecodeSigned4BitValue(extendedToken, 13, 16); instructionToken->_sampleOffsets[2] = DecodeSigned4BitValue(extendedToken, 17, 20); break; case InstructionTokenExtendedType::ResourceDim: instructionToken->_resourceTarget = DecodeValue<ResourceDimension>(extendedToken, 6, 10); instructionToken->_resourceStride = DecodeValue<uint8_t>(extendedToken, 11, 15); break; case InstructionTokenExtendedType::ResourceReturnType: instructionToken->_resourceReturnTypes[0] = DecodeValue<ResourceReturnType>(extendedToken, 6, 9); instructionToken->_resourceReturnTypes[1] = DecodeValue<ResourceReturnType>(extendedToken, 10, 13); instructionToken->_resourceReturnTypes[2] = DecodeValue<ResourceReturnType>(extendedToken, 14, 17); instructionToken->_resourceReturnTypes[3] = DecodeValue<ResourceReturnType>(extendedToken, 18, 21); break; default: throw new runtime_error("Unrecognised extended type"); } } if (header.OpcodeType == OpcodeType::InterfaceCall) { // Interface call // // OpcodeToken0: // // [10:00] D3D10_SB_OPCODE_INTERFACE_CALL // [23:11] Ignored, 0 // [30:24] Instruction length in DWORDs including the opcode token. // [31] 0 normally. 1 if extended operand definition, meaning next DWORD // contains extended operand description. If it is extended, then // it contains the actual instruction length in DWORDs, since // it may not fit into 7 bits if enough types are used. // // OpcodeToken0 is followed by a DWORD that gives the function index to // call in the function table specified for the given interface. // Next is the interface operand. instructionToken->_functionIndex = reader.ReadUInt32(); } while (reader.GetCurrentPosition() < instructionEnd) instructionToken->_operands.push_back(Operand::Parse(reader, header.OpcodeType)); return instructionToken; }