private static Dictionary <RegisterKey, HlslTreeNode> GetConstantOutputs(ShaderModel shader)
        {
            var constantTable = shader.ParseConstantTable();

            var constantOutputs = new Dictionary <RegisterKey, HlslTreeNode>();

            foreach (var constant in constantTable)
            {
                for (int i = 0; i < 4; i++)
                {
                    var destinationKey = new RegisterKey()
                    {
                        RegisterNumber = constant.RegisterIndex,
                        RegisterType   = RegisterType.Const,
                        ComponentIndex = i
                    };
                    var shaderInput = new HlslShaderInput()
                    {
                        InputDecl      = destinationKey,
                        ComponentIndex = i
                    };
                    constantOutputs.Add(destinationKey, shaderInput);
                }
            }

            return(constantOutputs);
        }
        private HlslTreeNode CreateInstructionTree(Instruction instruction, RegisterKey destinationKey)
        {
            int componentIndex = destinationKey.ComponentIndex;

            switch (instruction.Opcode)
            {
            case Opcode.Dcl:
            {
                var shaderInput = new HlslShaderInput()
                {
                    InputDecl      = destinationKey,
                    ComponentIndex = componentIndex
                };
                return(shaderInput);
            }

            case Opcode.Def:
            {
                var constant = new HlslConstant(instruction.GetParamSingle(componentIndex + 1));
                return(constant);
            }

            case Opcode.Abs:
            case Opcode.Add:
            case Opcode.Mad:
            case Opcode.Mov:
            case Opcode.Mul:
            {
                int numInputs;
                switch (instruction.Opcode)
                {
                case Opcode.Abs:
                case Opcode.Mov:
                    numInputs = 1;
                    break;

                case Opcode.Add:
                case Opcode.Mul:
                    numInputs = 2;
                    break;

                case Opcode.Mad:
                    numInputs = 3;
                    break;

                default:
                    throw new NotImplementedException();
                }
                var operation = new HlslOperation(instruction.Opcode);
                for (int j = 0; j < numInputs; j++)
                {
                    var modifier = instruction.GetSourceModifier(j + 1);
                    if (modifier != SourceModifier.None)
                    {
                        // TODO
                    }
                    var inputKey = GetParamRegisterKey(instruction, j + 1, componentIndex);
                    var input    = _activeOutputs[inputKey];
                    operation.AddChild(input);
                }

                return(operation);
            }

            default:
                throw new NotImplementedException();
            }
        }