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;
}
Example #7
0
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;
}
Example #12
0
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;
}
Example #18
0
shared_ptr<Sfi0Chunk> Sfi0Chunk::Parse(BytecodeReader& reader)
{
	auto unknown = reader.ReadInt32();
	assert(unknown == 2); // TODO: Unknown
	return shared_ptr<Sfi0Chunk>(new Sfi0Chunk());
}
Example #19
0
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;
}