Exemple #1
0
        virtual public ShaderModel ReadShader()
        {
            // Version token
            byte       minorVersion = ReadByte();
            byte       majorVersion = ReadByte();
            ShaderType shaderType   = (ShaderType)ReadUInt16();

            if (shaderType == ShaderType.Fx)
            {
                throw new Exception("FX shaders currently not supported");
            }
            Debug.Assert(shaderType == ShaderType.Pixel || shaderType == ShaderType.Vertex || shaderType == ShaderType.Fx,
                         $"Shader does not contain a valid shader type {shaderType}");
            var shader = new ShaderModel(majorVersion, minorVersion, shaderType);

            while (true)
            {
                Token instruction = ReadInstruction(shader);
                InstructionVerifier.Verify(instruction);
                shader.Tokens.Add(instruction);
                if (instruction.Opcode == Opcode.End)
                {
                    break;
                }
            }
            shader.ParseConstantTable();
            return(shader);
        }
Exemple #2
0
        private void LoadConstantOutputs(ShaderModel shader)
        {
            IList <ConstantDeclaration> constantTable = shader.ParseConstantTable().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 (int 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);
                        }
                    }
                }
            }
        }
        private void Load(ShaderModel shader)
        {
            ConstantDeclarations = shader.ParseConstantTable().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 (int 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.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:
                        MethodInputRegisters.Add(registerKey, registerDeclaration);
                        break;

                    case RegisterType.Output:
                    case RegisterType.ColorOut:
                        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);
                    int          registerNumber = instruction.GetParamRegisterNumber(destIndex);
                    var          registerKey    = new RegisterKey(registerType, registerNumber);
                    if (_registerDeclarations.ContainsKey(registerKey) == false)
                    {
                        var reg = new RegisterDeclaration(registerKey);
                        _registerDeclarations[registerKey] = reg;
                        if (registerType == RegisterType.ColorOut ||
                            registerType == RegisterType.RastOut ||
                            registerType == RegisterType.Output ||
                            registerType == RegisterType.AttrOut)
                        {
                            MethodOutputRegisters[registerKey] = reg;
                        }
                    }
                }
            }
        }
Exemple #4
0
 public AsmWriter(ShaderModel shader)
 {
     this.shader   = shader;
     constantTable = shader.ParseConstantTable();
 }