Beispiel #1
0
        void WriteInstruction(Instruction instruction)
        {
            switch (instruction.Opcode)
            {
            case Opcode.Abs:
                WriteLine("{0} = abs({1});", GetDestinationName(instruction),
                          GetSourceName(instruction, 1));
                break;

            case Opcode.Add:
                WriteLine("{0} = {1} + {2};", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Cmp:
                // TODO: should be per-component
                WriteLine("{0} = ({1} >= 0) ? {2} : {3};", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2), GetSourceName(instruction, 3));
                break;

            case Opcode.Def:
                var c = new Constant(
                    instruction.GetParamRegisterNumber(0),
                    instruction.GetParamSingle(1),
                    instruction.GetParamSingle(2),
                    instruction.GetParamSingle(3),
                    instruction.GetParamSingle(4));
                ConstantDefinitions.Add(c);
                break;

            case Opcode.DefI:
                var ci = new ConstantInt(instruction.GetParamRegisterNumber(0),
                                         instruction.Params[1],
                                         instruction.Params[2],
                                         instruction.Params[3],
                                         instruction.Params[4]);
                ConstantIntDefinitions.Add(ci);
                break;

            case Opcode.DP2Add:
                WriteLine("{0} = dot({1}, {2}) + {3};", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2), GetSourceName(instruction, 3));
                break;

            case Opcode.Dp3:
                WriteLine("{0} = dot({1}, {2});", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Dp4:
                WriteLine("{0} = dot({1}, {2});", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Else:
                indent = indent.Substring(0, indent.Length - 1);
                WriteLine("} else {");
                indent += "\t";
                break;

            case Opcode.Endif:
                indent = indent.Substring(0, indent.Length - 1);
                WriteLine("}");
                break;

            case Opcode.Exp:
                WriteLine("{0} = exp2({1});", GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.Frc:
                WriteLine("{0} = frac({1});", GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.If:
                WriteLine("if ({0}) {{", GetSourceName(instruction, 0));
                indent += "\t";
                break;

            case Opcode.IfC:
                if ((IfComparison)instruction.Modifier == IfComparison.GE &&
                    instruction.GetSourceModifier(0) == SourceModifier.AbsAndNegate &&
                    instruction.GetSourceModifier(1) == SourceModifier.Abs &&
                    instruction.GetParamRegisterName(0) + instruction.GetSourceSwizzleName(0) ==
                    instruction.GetParamRegisterName(1) + instruction.GetSourceSwizzleName(1))
                {
                    WriteLine("if ({0} == 0) {{", instruction.GetParamRegisterName(0) + instruction.GetSourceSwizzleName(0));
                }
                else if ((IfComparison)instruction.Modifier == IfComparison.LT &&
                         instruction.GetSourceModifier(0) == SourceModifier.AbsAndNegate &&
                         instruction.GetSourceModifier(1) == SourceModifier.Abs &&
                         instruction.GetParamRegisterName(0) + instruction.GetSourceSwizzleName(0) ==
                         instruction.GetParamRegisterName(1) + instruction.GetSourceSwizzleName(1))
                {
                    WriteLine("if ({0} != 0) {{", instruction.GetParamRegisterName(0) + instruction.GetSourceSwizzleName(0));
                }
                else
                {
                    string ifComparison;
                    switch ((IfComparison)instruction.Modifier)
                    {
                    case IfComparison.GT:
                        ifComparison = ">";
                        break;

                    case IfComparison.EQ:
                        ifComparison = "==";
                        break;

                    case IfComparison.GE:
                        ifComparison = ">=";
                        break;

                    case IfComparison.LE:
                        ifComparison = "<=";
                        break;

                    case IfComparison.NE:
                        ifComparison = "!=";
                        break;

                    case IfComparison.LT:
                        ifComparison = "<";
                        break;

                    default:
                        throw new InvalidOperationException();
                    }
                    WriteLine("if ({0} {2} {1}) {{", GetSourceName(instruction, 0), GetSourceName(instruction, 1), ifComparison);
                }
                indent += "\t";
                break;

            case Opcode.Log:
                WriteLine("{0} = log2({1});", GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.Lrp:
                WriteLine("{0} = lerp({2}, {3}, {1});", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2), GetSourceName(instruction, 3));
                break;

            case Opcode.Mad:
                WriteLine("{0} = {1} * {2} + {3};", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2), GetSourceName(instruction, 3));
                break;

            case Opcode.Max:
                WriteLine("{0} = max({1}, {2});", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Min:
                WriteLine("{0} = min({1}, {2});", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Mov:
                WriteLine("{0} = {1};", GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.MovA:
                WriteLine("{0} = {1};", GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.Mul:
                WriteLine("{0} = {1} * {2};", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Nrm:
                WriteLine("{0} = normalize({1});", GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.Pow:
                WriteLine("{0} = pow({1}, {2});", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Rcp:
                WriteLine("{0} = 1 / {1};", GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.Rsq:
                WriteLine("{0} = 1 / sqrt({1});", GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.Sge:
                if (instruction.GetSourceModifier(1) == SourceModifier.AbsAndNegate &&
                    instruction.GetSourceModifier(2) == SourceModifier.Abs &&
                    instruction.GetParamRegisterName(1) + instruction.GetSourceSwizzleName(1) ==
                    instruction.GetParamRegisterName(2) + instruction.GetSourceSwizzleName(2))
                {
                    WriteLine("{0} = ({1} == 0) ? 1 : 0;", GetDestinationName(instruction),
                              instruction.GetParamRegisterName(1) + instruction.GetSourceSwizzleName(1));
                }
                else
                {
                    WriteLine("{0} = ({1} >= {2}) ? 1 : 0;", GetDestinationName(instruction), GetSourceName(instruction, 1),
                              GetSourceName(instruction, 2));
                }
                break;

            case Opcode.Slt:
                WriteLine("{0} = ({1} < {2}) ? 1 : 0;", GetDestinationName(instruction), GetSourceName(instruction, 1),
                          GetSourceName(instruction, 2));
                break;

            case Opcode.SinCos:
                WriteLine("sincos({1}, {0}, {0});", GetDestinationName(instruction), GetSourceName(instruction, 1));
                break;

            case Opcode.Sub:
                WriteLine("{0} = {1} - {2};", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Tex:
                if ((shader.MajorVersion == 1 && shader.MinorVersion >= 4) || (shader.MajorVersion > 1))
                {
                    WriteLine("{0} = tex2D({2}, {1});", GetDestinationName(instruction),
                              GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                }
                else
                {
                    WriteLine("{0} = tex2D();", GetDestinationName(instruction));
                }
                break;

            case Opcode.TexLDL:
                WriteLine("{0} = tex2Dlod({2}, {1});", GetDestinationName(instruction),
                          GetSourceName(instruction, 1), GetSourceName(instruction, 2));
                break;

            case Opcode.Comment:
            case Opcode.End:
                break;
            }
        }
Beispiel #2
0
        string GetSourceConstantName(Instruction instruction, int srcIndex)
        {
            var registerType   = instruction.GetParamRegisterType(srcIndex);
            int registerNumber = instruction.GetParamRegisterNumber(srcIndex);

            switch (registerType)
            {
            case RegisterType.ConstBool:
                //throw new NotImplementedException();
                return(null);

            case RegisterType.ConstInt:
            {
                var constantInt = ConstantIntDefinitions.FirstOrDefault(x => x.RegisterIndex == registerNumber);
                if (constantInt == null)
                {
                    return(null);
                }
                byte[] swizzle  = instruction.GetSourceSwizzleComponents(srcIndex);
                uint[] constant =
                {
                    constantInt[swizzle[0]],
                    constantInt[swizzle[1]],
                    constantInt[swizzle[2]],
                    constantInt[swizzle[3]]
                };

                switch (instruction.GetSourceModifier(srcIndex))
                {
                case SourceModifier.None:
                    break;

                case SourceModifier.Negate:
                    throw new NotImplementedException();

                    /*
                     * for (int i = 0; i < 4; i++)
                     * {
                     *  constant[i] = -constant[i];
                     * }*/
                    break;

                default:
                    throw new NotImplementedException();
                }

                int destLength = instruction.GetDestinationMaskLength();
                switch (destLength)
                {
                case 1:
                    return(constant[0].ToString());

                case 2:
                    if (constant[0] == constant[1])
                    {
                        return(constant[0].ToString());
                    }
                    return($"int2({constant[0]}, {constant[1]})");

                case 3:
                    if (constant[0] == constant[1] && constant[0] == constant[2])
                    {
                        return(constant[0].ToString());
                    }
                    return($"int3({constant[0]}, {constant[1]}, {constant[2]})");

                case 4:
                    if (constant[0] == constant[1] && constant[0] == constant[2] && constant[0] == constant[3])
                    {
                        return(constant[0].ToString());
                    }
                    return($"int4({constant[0]}, {constant[1]}, {constant[2]}, {constant[3]})");

                default:
                    throw new InvalidOperationException();
                }
            }

            case RegisterType.Const:
            case RegisterType.Const2:
            case RegisterType.Const3:
            case RegisterType.Const4:
            {
                var constantRegister = ConstantDefinitions.FirstOrDefault(x => x.RegisterIndex == registerNumber);
                if (constantRegister == null)
                {
                    return(null);
                }

                byte[]  swizzle  = instruction.GetSourceSwizzleComponents(srcIndex);
                float[] constant =
                {
                    constantRegister[swizzle[0]],
                    constantRegister[swizzle[1]],
                    constantRegister[swizzle[2]],
                    constantRegister[swizzle[3]]
                };

                switch (instruction.GetSourceModifier(srcIndex))
                {
                case SourceModifier.None:
                    break;

                case SourceModifier.Negate:
                    for (int i = 0; i < 4; i++)
                    {
                        constant[i] = -constant[i];
                    }
                    break;

                default:
                    throw new NotImplementedException();
                }

                int destLength;
                if (instruction.HasDestination)
                {
                    destLength = instruction.GetDestinationMaskLength();
                }
                else
                {
                    if (instruction.Opcode == Opcode.If || instruction.Opcode == Opcode.IfC)
                    {
                        // TODO
                    }
                    destLength = 4;
                }
                switch (destLength)
                {
                case 1:
                    return(constant[0].ToString(CultureInfo.InvariantCulture));

                case 2:
                    if (constant[0] == constant[1])
                    {
                        return(constant[0].ToString(CultureInfo.InvariantCulture));
                    }
                    return(string.Format("float2({0}, {1})",
                                         constant[0].ToString(CultureInfo.InvariantCulture),
                                         constant[1].ToString(CultureInfo.InvariantCulture)));

                case 3:
                    if (constant[0] == constant[1] && constant[0] == constant[2])
                    {
                        return(constant[0].ToString(CultureInfo.InvariantCulture));
                    }
                    return(string.Format("float3({0}, {1}, {2})",
                                         constant[0].ToString(CultureInfo.InvariantCulture),
                                         constant[1].ToString(CultureInfo.InvariantCulture),
                                         constant[2].ToString(CultureInfo.InvariantCulture)));

                case 4:
                    if (constant[0] == constant[1] && constant[0] == constant[2] && constant[0] == constant[3])
                    {
                        return(constant[0].ToString(CultureInfo.InvariantCulture));
                    }
                    return(string.Format("float4({0}, {1}, {2}, {3})",
                                         constant[0].ToString(CultureInfo.InvariantCulture),
                                         constant[1].ToString(CultureInfo.InvariantCulture),
                                         constant[2].ToString(CultureInfo.InvariantCulture),
                                         constant[3].ToString(CultureInfo.InvariantCulture)));

                default:
                    throw new InvalidOperationException();
                }
            }

            default:
                return(null);
            }
        }