예제 #1
0
        private TextureLoadOutputNode CreateTextureLoadOutputNode(InstructionToken instruction, int outputComponent)
        {
            const int TextureCoordsIndex = 1;
            const int SamplerIndex       = 2;

            RegisterKey samplerRegister = instruction.GetParamRegisterKey(SamplerIndex);

            if (!_samplers.TryGetValue(samplerRegister, out HlslTreeNode samplerInput))
            {
                throw new InvalidOperationException();
            }
            var samplerRegisterInput       = (RegisterInputNode)samplerInput;
            int numSamplerOutputComponents = samplerRegisterInput.SamplerTextureDimension;

            IList <HlslTreeNode> texCoords = new List <HlslTreeNode>();

            for (int component = 0; component < numSamplerOutputComponents; component++)
            {
                RegisterComponentKey textureCoordsKey = GetParamRegisterComponentKey(instruction, TextureCoordsIndex, component);
                HlslTreeNode         textureCoord     = _activeOutputs[textureCoordsKey];
                texCoords.Add(textureCoord);
            }

            return(new TextureLoadOutputNode(samplerRegisterInput, texCoords, outputComponent));
        }
예제 #2
0
        public uint GetRegisterFullLength(RegisterKey registerKey)
        {
            if (registerKey.Type == RegisterType.Const)
            {
                var constant = FindConstant(ParameterType.Float, registerKey.Number);
                return(constant.Columns);
            }

            RegisterDeclaration decl = _registerDeclarations[registerKey];

            switch (decl.TypeName)
            {
            case "float":
                return(1);

            case "float2":
                return(2);

            case "float3":
                return(3);

            case "float4":
                return(4);

            default:
                throw new InvalidOperationException();
            }
        }
        public override int GetHashCode()
        {
            int hashCode =
                RegisterKey.GetHashCode() ^
                ComponentIndex.GetHashCode();

            return(hashCode);
        }
예제 #4
0
        private static RegisterComponentKey GetParamRegisterComponentKey(InstructionToken instruction, int paramIndex, int component)
        {
            RegisterKey registerKey = instruction.GetParamRegisterKey(paramIndex);

            byte[] swizzle        = instruction.GetSourceSwizzleComponents(paramIndex);
            int    componentIndex = swizzle[component];

            return(new RegisterComponentKey(registerKey, componentIndex));
        }
예제 #5
0
        private void LoadConstantOutputs(ShaderModel shader)
        {
            IList <ConstantDeclaration> constantTable = shader.ConstantTable.ConstantDeclarations;

            _activeOutputs = new Dictionary <RegisterComponentKey, HlslTreeNode>();
            _samplers      = new Dictionary <RegisterKey, HlslTreeNode>();

            foreach (var constant in constantTable)
            {
                for (uint r = 0; r < constant.RegisterCount; r++)
                {
                    var data = constant.GetRegisterTypeByOffset(r);
                    int samplerTextureDimension;
                    switch (data.Type.ParameterType)
                    {
                    case ParameterType.Sampler1D:
                        samplerTextureDimension = 1;
                        goto SamplerCommon;

                    case ParameterType.Sampler2D:
                        samplerTextureDimension = 2;
                        goto SamplerCommon;

                    case ParameterType.Sampler3D:
                    case ParameterType.SamplerCube:
                        samplerTextureDimension = 3;
                        goto SamplerCommon;
SamplerCommon:
                        {
                            var registerKey    = new RegisterKey(RegisterType.Sampler, constant.RegisterIndex + r);
                            var destinationKey = new RegisterComponentKey(registerKey, 0);
                            var shaderInput    = new RegisterInputNode(destinationKey, samplerTextureDimension);
                            _samplers.Add(registerKey, shaderInput);
                        }
                        break;

                    case ParameterType.Float:
                    {
                        var registerKey = new RegisterKey(RegisterType.Const, constant.RegisterIndex + r);
                        for (int i = 0; i < 4; i++)
                        {
                            var destinationKey = new RegisterComponentKey(registerKey, i);
                            var shaderInput    = new RegisterInputNode(destinationKey);
                            _activeOutputs.Add(destinationKey, shaderInput);
                        }
                    }
                    break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }
        }
예제 #6
0
        private void LoadConstantOutputs(ShaderModel shader)
        {
            IList <ConstantDeclaration> constantTable = shader.ConstantTable.ConstantDeclarations;

            _activeOutputs = new Dictionary <RegisterComponentKey, HlslTreeNode>();
            _samplers      = new Dictionary <RegisterKey, HlslTreeNode>();

            foreach (var constant in constantTable)
            {
                if (constant.RegisterSet == RegisterSet.Sampler)
                {
                    var registerKey    = new RegisterKey(RegisterType.Sampler, constant.RegisterIndex);
                    var destinationKey = new RegisterComponentKey(registerKey, 0);
                    int samplerTextureDimension;
                    switch (constant.ParameterType)
                    {
                    case ParameterType.Sampler1D:
                        samplerTextureDimension = 1;
                        break;

                    case ParameterType.Sampler2D:
                        samplerTextureDimension = 2;
                        break;

                    case ParameterType.Sampler3D:
                    case ParameterType.SamplerCube:
                        samplerTextureDimension = 3;
                        break;

                    default:
                        throw new InvalidOperationException();
                    }
                    var shaderInput = new RegisterInputNode(destinationKey, samplerTextureDimension);
                    _samplers.Add(registerKey, shaderInput);
                }
                else
                {
                    for (uint r = 0; r < constant.RegisterCount; r++)
                    {
                        if (constant.ParameterType != ParameterType.Float)
                        {
                            throw new NotImplementedException();
                        }
                        var registerKey = new RegisterKey(RegisterType.Const, constant.RegisterIndex + r);
                        for (int i = 0; i < 4; i++)
                        {
                            var destinationKey = new RegisterComponentKey(registerKey, i);
                            var shaderInput    = new RegisterInputNode(destinationKey);
                            _activeOutputs.Add(destinationKey, shaderInput);
                        }
                    }
                }
            }
        }
        public RegisterDeclaration(RegisterKey registerKey)
        {
            RegisterType type = registerKey.Type;

            _semantic   = GuessSemanticByRegisterType(type);
            RegisterKey = registerKey;
            if (_semantic != null && RegisterKey.Number != 0)
            {
                _semantic += registerKey.Number;
            }
            _maskedLength = 4;
        }
예제 #8
0
        public string GetDestinationName(InstructionToken instruction)
        {
            int         destIndex   = instruction.GetDestinationParamIndex();
            RegisterKey registerKey = instruction.GetParamRegisterKey(destIndex);

            string registerName = GetRegisterName(registerKey);

            registerName = registerName ?? instruction.GetParamRegisterName(destIndex);
            var    registerLength = GetRegisterFullLength(registerKey);
            string writeMaskName  = instruction.GetDestinationWriteMaskName(registerLength, true);

            return(string.Format("{0}{1}", registerName, writeMaskName));
        }
예제 #9
0
        private static IEnumerable <RegisterComponentKey> GetDestinationKeys(InstructionToken instruction)
        {
            int         index       = instruction.GetDestinationParamIndex();
            RegisterKey registerKey = instruction.GetParamRegisterKey(index);

            if (registerKey.Type == RegisterType.Sampler)
            {
                yield break;
            }

            ComponentFlags mask = instruction.GetDestinationWriteMask();

            for (int component = 0; component < 4; component++)
            {
                if ((mask & (ComponentFlags)(1 << component)) == 0)
                {
                    continue;
                }

                yield return(new RegisterComponentKey(registerKey, component));
            }
        }
예제 #10
0
        public uint GetRegisterFullLength(RegisterKey registerKey)
        {
            if (registerKey.Type == RegisterType.Const)
            {
                var constant = FindConstant(registerKey.Number);
                var data     = constant.GetRegisterTypeByOffset(registerKey.Number - constant.RegisterIndex);
                if (data.Type.ParameterType != ParameterType.Float)
                {
                    throw new NotImplementedException();
                }
                if (data.Type.ParameterClass == ParameterClass.MatrixColumns)
                {
                    return(data.Type.Rows);
                }
                return(data.Type.Columns);
            }

            RegisterDeclaration decl = _registerDeclarations[registerKey];

            switch (decl.TypeName)
            {
            case "float":
                return(1);

            case "float2":
                return(2);

            case "float3":
                return(3);

            case "float4":
                return(4);

            default:
                throw new InvalidOperationException();
            }
        }
 public RegisterComponentKey(RegisterKey registerKey, int componentIndex)
 {
     RegisterKey    = registerKey ?? throw new ArgumentNullException(nameof(registerKey));
     ComponentIndex = componentIndex;
 }
 public RegisterComponentKey(RegisterType registerType, uint registerNumber, int componentIndex)
 {
     RegisterKey    = new RegisterKey(registerType, registerNumber);
     ComponentIndex = componentIndex;
 }
예제 #13
0
        void WriteTemps()
        {
            Dictionary <RegisterKey, int> tempRegisters = new Dictionary <RegisterKey, int>();

            foreach (var inst in _shader.Instructions)
            {
                foreach (var operand in inst.Operands)
                {
                    if (operand is DestinationOperand dest)
                    {
                        if (dest.RegisterType == RegisterType.Temp)
                        {
                            var registerKey = new RegisterKey(dest.RegisterType, dest.RegisterNumber);
                            if (!tempRegisters.ContainsKey(registerKey))
                            {
                                var reg = new RegisterDeclaration(registerKey);
                                _registers._registerDeclarations[registerKey] = reg;
                                tempRegisters[registerKey] = (int)inst.GetDestinationWriteMask();
                            }
                            else
                            {
                                tempRegisters[registerKey] |= (int)inst.GetDestinationWriteMask();
                            }
                        }
                    }
                }
            }
            if (tempRegisters.Count == 0)
            {
                return;
            }
            foreach (IGrouping <int, RegisterKey> group in tempRegisters.GroupBy(
                         kv => kv.Value,
                         kv => kv.Key))
            {
                int    writeMask = group.Key;
                string writeMaskName; switch (writeMask)
                {
                case 0x1:
                    writeMaskName = "float";
                    break;

                case 0x3:
                    writeMaskName = "float2";
                    break;

                case 0x7:
                    writeMaskName = "float3";
                    break;

                case 0xF:
                    writeMaskName = "float4";
                    break;

                default:
                    // TODO
                    writeMaskName = "float4";
                    break;
                    //throw new NotImplementedException();
                }
                WriteIndent();
                WriteLine("{0} {1};", writeMaskName, string.Join(", ", group));
            }
        }
예제 #14
0
        private void Load(ShaderModel shader)
        {
            ConstantDeclarations = shader.ConstantTable.ConstantDeclarations;
            foreach (var constantDeclaration in ConstantDeclarations)
            {
                RegisterType registerType;
                switch (constantDeclaration.RegisterSet)
                {
                case RegisterSet.Bool:
                    registerType = RegisterType.ConstBool;
                    break;

                case RegisterSet.Float4:
                    registerType = RegisterType.Const;
                    break;

                case RegisterSet.Int4:
                    registerType = RegisterType.ConstInt;
                    break;

                case RegisterSet.Sampler:
                    registerType = RegisterType.Sampler;
                    break;

                default:
                    throw new InvalidOperationException();
                }
                if (registerType == RegisterType.Sampler)
                {
                    // Use declaration from declaration instruction instead
                    continue;
                }
                for (uint r = 0; r < constantDeclaration.RegisterCount; r++)
                {
                    var registerKey         = new RegisterKey(registerType, constantDeclaration.RegisterIndex + r);
                    var registerDeclaration = new RegisterDeclaration(registerKey);
                    _registerDeclarations.Add(registerKey, registerDeclaration);
                }
            }

            foreach (var instruction in shader.Tokens.OfType <InstructionToken>().Where(i => i.HasDestination))
            {
                if (instruction.Opcode == Opcode.Dcl)
                {
                    var         registerDeclaration = new RegisterDeclaration(instruction);
                    RegisterKey registerKey         = registerDeclaration.RegisterKey;

                    _registerDeclarations.Add(registerKey, registerDeclaration);

                    switch (registerKey.Type)
                    {
                    case RegisterType.Input:
                    case RegisterType.MiscType:
                    case RegisterType.Texture when shader.Type == ShaderType.Pixel:
                        MethodInputRegisters.Add(registerKey, registerDeclaration);
                        break;

                    case RegisterType.Output:
                    case RegisterType.ColorOut:
                    case RegisterType.AttrOut when shader.MajorVersion == 3 && shader.Type == ShaderType.Vertex:
                        MethodOutputRegisters.Add(registerKey, registerDeclaration);
                        break;

                    case RegisterType.Sampler:
                    case RegisterType.Addr:
                        break;

                    default:
                        throw new Exception($"Unexpected dcl {registerKey.Type}");
                    }
                }
                else if (instruction.Opcode == Opcode.Def)
                {
                    var constant = new Constant(
                        instruction.GetParamRegisterNumber(0),
                        instruction.GetParamSingle(1),
                        instruction.GetParamSingle(2),
                        instruction.GetParamSingle(3),
                        instruction.GetParamSingle(4));
                    _constantDefinitions.Add(constant);
                }
                else if (instruction.Opcode == Opcode.DefI)
                {
                    var constantInt = new ConstantInt(instruction.GetParamRegisterNumber(0),
                                                      instruction.Data[1],
                                                      instruction.Data[2],
                                                      instruction.Data[3],
                                                      instruction.Data[4]);
                    _constantIntDefinitions.Add(constantInt);
                }
                else
                {
                    // Find all assignments to color outputs, because pixel shader outputs are not declared.
                    int          destIndex      = instruction.GetDestinationParamIndex();
                    RegisterType registerType   = instruction.GetParamRegisterType(destIndex);
                    var          registerNumber = instruction.GetParamRegisterNumber(destIndex);
                    var          registerKey    = new RegisterKey(registerType, registerNumber);
                    if (_registerDeclarations.ContainsKey(registerKey) == false)
                    {
                        var reg = new RegisterDeclaration(registerKey);
                        _registerDeclarations[registerKey] = reg;
                        switch (registerType)
                        {
                        case RegisterType.AttrOut:
                        case RegisterType.ColorOut:
                        case RegisterType.DepthOut:
                        case RegisterType.Output:
                        case RegisterType.RastOut:
                            MethodOutputRegisters[registerKey] = reg;
                            break;
                        }
                    }
                }
            }
        }
예제 #15
0
        public string GetRegisterName(RegisterKey registerKey)
        {
            var decl = _registerDeclarations[registerKey];

            switch (registerKey.Type)
            {
            case RegisterType.Texture:
            case RegisterType.Input:
                return((MethodInputRegisters.Count == 1) ? decl.Name : ("i." + decl.Name));

            case RegisterType.RastOut:
            case RegisterType.Output:
            case RegisterType.AttrOut:
            case RegisterType.ColorOut:
                return((MethodOutputRegisters.Count == 1) ? decl.Name : ("o." + decl.Name));

            case RegisterType.Const:
                var constDecl      = FindConstant(registerKey.Number);
                var relativeOffset = registerKey.Number - constDecl.RegisterIndex;
                var name           = constDecl.GetMemberNameByOffset(relativeOffset);
                var data           = constDecl.GetRegisterTypeByOffset(relativeOffset);

                // sanity check
                var registersOccupied = data.Type.ParameterClass == ParameterClass.MatrixColumns
                                                ? data.Type.Columns
                                                : data.Type.Rows;
                if (registersOccupied == 1 && data.RegisterIndex != registerKey.Number)
                {
                    throw new InvalidOperationException();
                }

                switch (data.Type.ParameterType)
                {
                case ParameterType.Float:
                    if (registersOccupied == 1)
                    {
                        return(name);
                    }
                    var subElement = (registerKey.Number - data.RegisterIndex).ToString();
                    return(ColumnMajorOrder
                                                                ? $"transpose({name})[{subElement}]" // subElement = col
                                                                : $"{name}[{subElement}]");          // subElement = row;

                default:
                    throw new NotImplementedException();
                }

            case RegisterType.Sampler:
                ConstantDeclaration samplerDecl = FindConstant(RegisterSet.Sampler, registerKey.Number);
                if (samplerDecl != null)
                {
                    var offset = registerKey.Number - samplerDecl.RegisterIndex;
                    return(samplerDecl.GetMemberNameByOffset(offset));
                }
                else
                {
                    throw new NotImplementedException();
                }

            case RegisterType.MiscType:
                switch (registerKey.Number)
                {
                case 0:
                    return("vFace");

                case 1:
                    return("vPos");

                default:
                    throw new NotImplementedException();
                }

            case RegisterType.Temp:
                return(registerKey.ToString());

            default:
                throw new NotImplementedException();
            }
        }
예제 #16
0
        public string GetRegisterName(RegisterKey registerKey)
        {
            var decl = _registerDeclarations[registerKey];

            switch (registerKey.Type)
            {
            case RegisterType.Texture:
            case RegisterType.Input:
                return((MethodInputRegisters.Count == 1) ? decl.Name : ("i." + decl.Name));

            case RegisterType.RastOut:
            case RegisterType.Output:
            case RegisterType.AttrOut:
            case RegisterType.ColorOut:
                return((MethodOutputRegisters.Count == 1) ? decl.Name : ("o." + decl.Name));

            case RegisterType.Const:
                var constDecl = FindConstant(ParameterType.Float, registerKey.Number);
                if (ColumnMajorOrder)
                {
                    if (constDecl.Rows == 1)
                    {
                        return(constDecl.Name);
                    }
                    string col = (registerKey.Number - constDecl.RegisterIndex).ToString();
                    return($"transpose({constDecl.Name})[{col}]");
                }
                if (constDecl.Rows == 1)
                {
                    return(constDecl.Name);
                }
                string row = (registerKey.Number - constDecl.RegisterIndex).ToString();
                return(constDecl.Name + $"[{row}]");

            case RegisterType.Sampler:
                ConstantDeclaration samplerDecl = FindConstant(RegisterSet.Sampler, registerKey.Number);
                if (samplerDecl != null)
                {
                    return(samplerDecl.Name);
                }
                else
                {
                    throw new NotImplementedException();
                }

            case RegisterType.MiscType:
                switch (registerKey.Number)
                {
                case 0:
                    return("vFace");

                case 1:
                    return("vPos");

                default:
                    throw new NotImplementedException();
                }

            case RegisterType.Temp:
                return(registerKey.ToString());

            default:
                throw new NotImplementedException();
            }
        }
예제 #17
0
        public string GetSourceName(InstructionToken instruction, int srcIndex)
        {
            string      sourceRegisterName;
            RegisterKey registerKey  = instruction.GetParamRegisterKey(srcIndex);
            var         registerType = instruction.GetParamRegisterType(srcIndex);

            switch (registerType)
            {
            case RegisterType.Const:
            case RegisterType.Const2:
            case RegisterType.Const3:
            case RegisterType.Const4:
            case RegisterType.ConstBool:
            case RegisterType.ConstInt:
                sourceRegisterName = GetSourceConstantName(instruction, srcIndex);
                if (sourceRegisterName != null)
                {
                    return(sourceRegisterName);
                }

                ParameterType parameterType;
                switch (registerType)
                {
                case RegisterType.Const:
                case RegisterType.Const2:
                case RegisterType.Const3:
                case RegisterType.Const4:
                    parameterType = ParameterType.Float;
                    break;

                case RegisterType.ConstBool:
                    parameterType = ParameterType.Bool;
                    break;

                case RegisterType.ConstInt:
                    parameterType = ParameterType.Int;
                    break;

                default:
                    throw new NotImplementedException();
                }
                var registerNumber       = instruction.GetParamRegisterNumber(srcIndex);
                ConstantDeclaration decl = FindConstant(registerNumber);
                if (decl == null)
                {
                    // Constant register not found in def statements nor the constant table
                    //TODO:
                    return($"Error {registerType}{registerNumber}");
                    //throw new NotImplementedException();
                }
                var totalOffset      = registerNumber - decl.RegisterIndex;
                var data             = decl.GetRegisterTypeByOffset(totalOffset);
                var offsetFromMember = registerNumber - data.RegisterIndex;
                sourceRegisterName = decl.GetMemberNameByOffset(totalOffset);
                if (data.Type.ParameterClass == ParameterClass.MatrixRows)
                {
                    sourceRegisterName = string.Format("{0}[{1}]", decl.Name, offsetFromMember);
                }
                else if (data.Type.ParameterClass == ParameterClass.MatrixColumns)
                {
                    sourceRegisterName = string.Format("transpose({0})[{1}]", decl.Name, offsetFromMember);
                }
                break;

            default:
                sourceRegisterName = GetRegisterName(registerKey);
                break;
            }

            sourceRegisterName = sourceRegisterName ?? instruction.GetParamRegisterName(srcIndex);

            sourceRegisterName += instruction.GetSourceSwizzleName(srcIndex, true);
            return(ApplyModifier(instruction.GetSourceModifier(srcIndex), sourceRegisterName));
        }