示例#1
0
		public static Number4 ApplyOperandSelectionMode(Number4 value, Operand operand)
		{
			switch (operand.SelectionMode)
			{
				case Operand4ComponentSelectionMode.Swizzle:
				case Operand4ComponentSelectionMode.Select1:
					return Number4.Swizzle(value, operand.Swizzles);
				default:
					throw new ArgumentOutOfRangeException();
			}
		}
        private static string ApplyOperandSelectionMode(string register, Operand operand, bool forUseInArrayIndex)
        {
	        switch (operand.SelectionMode)
	        {
		        case Operand4ComponentSelectionMode.Select1:
					if (forUseInArrayIndex)
						return string.Format("{0}.Int{1}", register, (int) operand.Swizzles[0]);
			        goto case Operand4ComponentSelectionMode.Swizzle;
		        case Operand4ComponentSelectionMode.Swizzle:
			        if (operand.Swizzles[0] == Operand4ComponentName.X
				        && operand.Swizzles[1] == Operand4ComponentName.Y
				        && operand.Swizzles[2] == Operand4ComponentName.Z
				        && operand.Swizzles[3] == Operand4ComponentName.W)
				        return register;

			        return string.Format("{0}.{1}{2}{3}{4}", register,
				        GetOperand4ComponentName(operand.Swizzles[0]),
				        GetOperand4ComponentName(operand.Swizzles[1]).ToLower(),
				        GetOperand4ComponentName(operand.Swizzles[2]).ToLower(),
				        GetOperand4ComponentName(operand.Swizzles[3]).ToLower());
				default :
					throw new ArgumentOutOfRangeException();
	        }
        }
        private static string GenerateGetOperandValue(Operand operand, NumberType numberType, 
			string contextName = "context", bool forUseInArrayIndex = false)
        {
            switch (operand.OperandType)
            {
                case OperandType.Immediate32 :
                case OperandType.Immediate64:
                    Number4 immediateValues;
                    switch (operand.NumComponents)
                    {
                        case 1:
                            immediateValues = operand.ImmediateValues.Xxxx;
                            break;
                        case 4:
                            immediateValues = operand.ImmediateValues;
                            break;
                        default:
                            throw new NotImplementedException();
                    }
                    var value = OperandUtility.ApplyOperandModifier(immediateValues, numberType, operand.Modifier);
                    return string.Format("new Number4({0}f, {1}f, {2}f, {3}f)",
                        value.Float0, value.Float1, value.Float2, value.Float3);
                case OperandType.ConstantBuffer:
                case OperandType.IndexableTemp:
                case OperandType.Input:
                case OperandType.Temp:
					var swizzled = ApplyOperandSelectionMode(GetRegister(operand, contextName), operand, forUseInArrayIndex);
                    switch (operand.Modifier)
                    {
                        case OperandModifier.None:
                            return swizzled;
                        case OperandModifier.Neg:
                            return string.Format("Number4.Negate{0}({1})", numberType, swizzled);
                        case OperandModifier.Abs:
                            throw new NotImplementedException();
                        case OperandModifier.AbsNeg:
                            throw new NotImplementedException();
                        default :
                            throw new ArgumentOutOfRangeException();
                    }
                default:
                    throw new ArgumentException("Unsupported operand type: " + operand.OperandType);
            }
        }
        private static string GetRegisterIndex(Operand operand)
        {
	        switch (operand.IndexDimension)
	        {
		        case OperandIndexDimension._1D:
					// Only geometry shaders use 2D input values, but we always need to
					// use 2D indices because we use a 2D input array.
			        if (operand.OperandType == OperandType.Input)
				        return string.Format("[0][{0}]",
					        GetRegisterIndex(operand.Indices[0]));
			        return string.Format("[{0}]",
				        GetRegisterIndex(operand.Indices[0]));
		        case OperandIndexDimension._2D:
					return string.Format("[{0}][{1}]",
						GetRegisterIndex(operand.Indices[0]),
						GetRegisterIndex(operand.Indices[1]));
		        default:
			        throw new ArgumentOutOfRangeException();
	        }
        }
 private static string GetRegister(Operand operand, string contextName = "context")
 {
     if (operand.OperandType == OperandType.ConstantBuffer)
         return string.Format("virtualMachine.{0}{1}", 
             GetRegisterName(operand.OperandType),
             GetRegisterIndex(operand));
     return string.Format("{0}.{1}{2}", contextName,
         GetRegisterName(operand.OperandType),
         GetRegisterIndex(operand));
 }
        private static void GenerateSetRegisterValueScalar(StringBuilder sb, Operand operand)
        {
            var register = GetRegister(operand);

            if (operand.ComponentMask.HasFlag(ComponentMask.X))
                sb.AppendLineIndent(2, "    {0}.Number0 = result;", register);
            if (operand.ComponentMask.HasFlag(ComponentMask.Y))
                sb.AppendLineIndent(2, "    {0}.Number1 = result;", register);
            if (operand.ComponentMask.HasFlag(ComponentMask.Z))
                sb.AppendLineIndent(2, "    {0}.Number2 = result;", register);
            if (operand.ComponentMask.HasFlag(ComponentMask.W))
                sb.AppendLineIndent(2, "    {0}.Number3 = result;", register);
        }
        private static void GenerateSetRegisterValue(StringBuilder sb, Operand operand, string contextName = "context")
        {
            var register = GetRegister(operand, contextName);

            if (operand.ComponentMask.HasFlag(ComponentMask.X)
                && operand.ComponentMask.HasFlag(ComponentMask.Y)
                && operand.ComponentMask.HasFlag(ComponentMask.Z)
                && operand.ComponentMask.HasFlag(ComponentMask.W))
            {
                sb.AppendLineIndent(2, "    {0} = result;", register);
                return;
            }

            if (operand.ComponentMask.HasFlag(ComponentMask.X))
                sb.AppendLineIndent(2, "    {0}.Number0 = result.Number0;", register);
            if (operand.ComponentMask.HasFlag(ComponentMask.Y))
                sb.AppendLineIndent(2, "    {0}.Number1 = result.Number1;", register);
            if (operand.ComponentMask.HasFlag(ComponentMask.Z))
                sb.AppendLineIndent(2, "    {0}.Number2 = result.Number2;", register);
            if (operand.ComponentMask.HasFlag(ComponentMask.W))
                sb.AppendLineIndent(2, "    {0}.Number3 = result.Number3;", register);
        }
示例#8
0
		private static void SetRegisterValue(ExecutionContext context, Operand operand, Number4 value)
		{
			Number4[] register;
			int index;
			GetRegister(context, operand, out register, out index);
			register[index].WriteMaskedValue(value, operand.ComponentMask);
		}
示例#9
0
		private static RegisterIndex GetRegisterIndex(ExecutionContext context, Operand operand)
		{
			var result = new RegisterIndex();
			switch (operand.IndexDimension)
			{
				case OperandIndexDimension._1D:
					result.Index1D = EvaluateOperandIndex(context, operand.Indices[0]);
					break;
				case OperandIndexDimension._2D:
					result.Index2D_0 = EvaluateOperandIndex(context, operand.Indices[0]);
					result.Index2D_1 = EvaluateOperandIndex(context, operand.Indices[1]);
					break;
			}
			return result;
		}
示例#10
0
		/// <summary>
		/// Gets potentially-swizzled value for use on RHS of an operation.
		/// </summary>
		private static Number4 GetOperandValue(ExecutionContext context, Operand operand, NumberType numberType)
		{
			switch (operand.OperandType)
			{
				case OperandType.Immediate32:
                case OperandType.Immediate64:
			        Number4 value;
                    switch (operand.NumComponents)
                    {
                        case 1 :
                            value = operand.ImmediateValues.Xxxx;
                            break;
                        case 4 :
                            value = operand.ImmediateValues;
                            break;
                        default :
                            throw new NotImplementedException();
                    }
                    return OperandUtility.ApplyOperandModifier(value, numberType, operand.Modifier);
                case OperandType.ConstantBuffer:
				case OperandType.IndexableTemp:
				case OperandType.Input:
				case OperandType.Temp:
					Number4[] register;
					int index;
					GetRegister(context, operand, out register, out index);
					var swizzledNumber = OperandUtility.ApplyOperandSelectionMode(register[index], operand);
					return OperandUtility.ApplyOperandModifier(swizzledNumber, numberType, operand.Modifier);
				default:
					throw new ArgumentException("Unsupported operand type: " + operand.OperandType);
			}
		}
示例#11
0
		private static void GetRegister(ExecutionContext context, Operand operand, out Number4[] register, out int index)
		{
			var registerIndex = GetRegisterIndex(context, operand);
			context.GetRegister(operand.OperandType, registerIndex, out register, out index);
		}
示例#12
0
		public static Operand Parse(BytecodeReader reader, OpcodeType parentType)
		{
			uint token0 = reader.ReadUInt32();
		    if (token0 == 0)
		        return null;

			var operand = new Operand(parentType);

			var numComponents = token0.DecodeValue<OperandNumComponents>(0, 1);
			switch (numComponents)
			{
				case OperandNumComponents.Zero:
					{
						operand.NumComponents = 0;
						break;
					}
				case OperandNumComponents.One:
					{
						operand.NumComponents = 1;
						break;
					}
				case OperandNumComponents.Four:
					{
						operand.NumComponents = 4;
						operand.SelectionMode = token0.DecodeValue<Operand4ComponentSelectionMode>(2, 3);
						switch (operand.SelectionMode)
						{
							case Operand4ComponentSelectionMode.Mask:
								{
									operand.ComponentMask = token0.DecodeValue<ComponentMask>(4, 7);
									break;
								}
							case Operand4ComponentSelectionMode.Swizzle:
								{
									var swizzle = token0.DecodeValue(4, 11);
									Func<uint, byte, Operand4ComponentName> swizzleDecoder = (s, i) =>
										(Operand4ComponentName) ((s >> (i * 2)) & 3);
									operand.Swizzles[0] = swizzleDecoder(swizzle, 0);
									operand.Swizzles[1] = swizzleDecoder(swizzle, 1);
									operand.Swizzles[2] = swizzleDecoder(swizzle, 2);
									operand.Swizzles[3] = swizzleDecoder(swizzle, 3);
									break;
								}
							case Operand4ComponentSelectionMode.Select1:
								{
									var swizzle = token0.DecodeValue<Operand4ComponentName>(4, 5);
									operand.Swizzles[0] = operand.Swizzles[1] = operand.Swizzles[2] = operand.Swizzles[3] = swizzle;
									break;
								}
							default:
								{
									throw new ParseException("Unrecognized selection method: " + operand.SelectionMode);
								}
						}
						break;
					}
				case OperandNumComponents.N:
					{
						throw new ParseException("OperandNumComponents.N is not currently supported.");
					}
			}

			operand.OperandType = token0.DecodeValue<OperandType>(12, 19);
			operand.IndexDimension = token0.DecodeValue<OperandIndexDimension>(20, 21);

			operand.IsExtended = token0.DecodeValue(31, 31) == 1;
			if (operand.IsExtended)
				ReadExtendedOperand(operand, reader);

			Func<uint, byte, OperandIndexRepresentation> indexRepresentationDecoder = (t, i) =>
				(OperandIndexRepresentation) t.DecodeValue((byte) (22 + (i * 3)), (byte) (22 + (i * 3) + 2));

			for (byte i = 0; i < (byte) operand.IndexDimension; i++)
			{
				operand.Indices[i] = new OperandIndex();

				var indexRepresentation = indexRepresentationDecoder(token0, i);
				operand.Indices[i].Representation = indexRepresentation;

				switch (indexRepresentation)
				{
					case OperandIndexRepresentation.Immediate32:
						operand.Indices[i].Value = reader.ReadUInt32();
						break;
					case OperandIndexRepresentation.Immediate64:
						operand.Indices[i].Value = reader.ReadUInt64();
						goto default;
					case OperandIndexRepresentation.Relative:
						operand.Indices[i].Register = Parse(reader, parentType);
						break;
					case OperandIndexRepresentation.Immediate32PlusRelative:
						operand.Indices[i].Value = reader.ReadUInt32();
						goto case OperandIndexRepresentation.Relative;
					case OperandIndexRepresentation.Immediate64PlusRelative:
						operand.Indices[i].Value = reader.ReadUInt64();
						goto case OperandIndexRepresentation.Relative;
					default:
						throw new ParseException("Unrecognised index representation: " + indexRepresentation);
				}
			}

			var numberType = parentType.GetNumberType();
			switch (operand.OperandType)
			{
				case OperandType.Immediate32:
				{
					var immediateValues = new Number4();
					for (var i = 0; i < operand.NumComponents; i++)
						immediateValues.SetNumber(i, Number.Parse(reader));
					operand.ImmediateValues = immediateValues;
					break;
				}
				case OperandType.Immediate64:
				{
					var immediateValues = new Number4();
					for (var i = 0; i < operand.NumComponents; i++)
						immediateValues.SetDouble(i, reader.ReadDouble());
					operand.ImmediateValues = immediateValues;
					break;
				}
			}

			return operand;
		}
示例#13
0
		/// <summary>
		/// Extended Instruction Operand Format (OperandToken1)
		///
		/// If bit31 of an operand token is set, the
		/// operand has additional data in a second DWORD
		/// directly following OperandToken0.  Other tokens
		/// expected for the operand, such as immmediate
		/// values or relative address operands (full
		/// operands in themselves) always follow
		/// OperandToken0 AND OperandToken1..n (extended
		/// operand tokens, if present).
		///
		/// [05:00] D3D10_SB_EXTENDED_OPERAND_TYPE
		/// [30:06] if([05:00] == D3D10_SB_EXTENDED_OPERAND_MODIFIER)
		///         {
		///              [13:06] D3D10_SB_OPERAND_MODIFIER
		///              [30:14] Ignored, 0.
		///         }
		///         else
		///         {
		///              [30:06] Ignored, 0.
		///         }
		/// [31]    0 normally. 1 if second order extended operand definition,
		///         meaning next DWORD contains yet ANOTHER extended operand
		///         description. Currently no second order extensions defined.
		///         This would be useful if a particular extended operand does
		///         not have enough space to store the required information in
		///         a single token and so is extended further.
		/// </summary>
		private static void ReadExtendedOperand(Operand operand, BytecodeReader reader)
		{
			uint token1 = reader.ReadUInt32();

			switch (token1.DecodeValue<ExtendedOperandType>(0, 5))
			{
				case ExtendedOperandType.Modifier:
					operand.Modifier = token1.DecodeValue<OperandModifier>(6, 13);
					break;
			}
		}