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
			};
		}
Exemple #6
0
		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;
		}
Exemple #11
0
		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;
		}