Exemplo n.º 1
0
        private void SetupCommonRegisters()
        {
            Dictionary <string, Register> common = new Dictionary <string, Register>();

            AsmListing[] listings = new AsmListing[] { vsListing, psListing, vsPreshaderListing, psPreshaderListing };

            foreach (AsmListing listing in listings)
            {
                if (listing == null)
                {
                    continue;
                }

                for (int i = 0; i < listing.RegisterSet.RegisterCount; i++)
                {
                    Register reg = listing.RegisterSet.GetRegister(i);

                    if (!common.ContainsKey(reg.Name))
                    {
                        common.Add(reg.Name, reg);
                    }
                }
            }

            Register[] registers = new Register[common.Count];
            int        count     = 0;

            foreach (Register reg in common.Values)
            {
                registers[count++] = reg;
            }

            this.registers = new RegisterSet(registers);
        }
Exemplo n.º 2
0
        private void ProcessShader(string asm, out AsmListing shader, out AsmListing preshader, out string comment)
        {
            preshader = null;

            //format:

            //either,

            /*
             * //header
             * preshader
             * //header
             * shader
             * //comment
             */

            //or

            /*
             * //header
             * shader
             * //comment
             */

            string[] asmLinesSource = asm.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
            //ignore first and last line (the { and })
            string[] asmLines = new string[Math.Max(0, asmLinesSource.Length - 2)];
            for (int i = 1; i < asmLinesSource.Length - 1; i++)
            {
                asmLines[i - 1] = asmLinesSource[i].Trim();
            }

            comment = "";
            if (asmLines.Length > 0)
            {
                comment = asmLines[asmLines.Length - 1];
                if (comment.StartsWith("// "))
                {
                    comment = comment.Substring(3);
                }
            }

            bool[] isComment = new bool[asmLines.Length];

            for (int i = 0; i < asmLines.Length - 1; i++)
            {
                isComment[i] = asmLines[i].StartsWith("//");
            }

            //top header
            int headerLength = 0;
            int start        = 0;

            for (int i = 1; i < asmLines.Length; i++)
            {
                if (!isComment[i] && asmLines[i].Length != 0)
                {
                    break;
                }

                headerLength = i + 1;
                start        = i + 1;
            }

            int firstBlockLength = 0;
            int firstBlockStart  = start;

            for (int i = start; i < asmLines.Length; i++)
            {
                firstBlockLength = i - headerLength + 1;
                start            = i + 1;

                if (isComment[i])
                {
                    break;
                }
            }

            int secondHeaderLength = 0;
            int secondHeaderStart  = start;

            for (int i = start; i < asmLines.Length; i++)
            {
                if (!isComment[i] && asmLines[i].Length != 0)
                {
                    break;
                }

                secondHeaderLength = i - firstBlockLength + 1;
                start = i + 1;
            }

            int secondBlockLength = 0;
            int secondBlockStart  = start;

            for (int i = start; i < asmLines.Length; i++)
            {
                secondBlockLength = i - secondHeaderLength + 1;
                start             = i + 1;

                if (isComment[i])
                {
                    break;
                }
            }

            if (secondHeaderLength > 0 &&
                secondBlockLength > 0)
            {
                //preshader is used
                preshader = new AsmListing(CombineLines(asmLines, firstBlockStart, firstBlockLength), new RegisterSet(CombineLines(asmLines, 1, headerLength)));
                shader    = new AsmListing(CombineLines(asmLines, secondBlockStart, secondBlockLength), new RegisterSet(CombineLines(asmLines, secondHeaderStart, secondHeaderLength)));
            }
            else
            {
                //no preshader
                shader = new AsmListing(CombineLines(asmLines, firstBlockStart, firstBlockLength), new RegisterSet(CombineLines(asmLines, 1, headerLength)));
            }
        }
Exemplo n.º 3
0
        public AsmToHlslAsmConverter(AsmListing asmSource, Microsoft.Xna.Framework.TargetPlatform platform, int shaderMaxConstants, int shaderMaxBooleanConstants, bool throwOnError)
        {
            maxConstant = -1;
            if (shaderMaxConstants != 0)
            {
                maxConstant = shaderMaxConstants;
            }
            maxBoolean = -1;
            if (shaderMaxBooleanConstants != 0)
            {
                maxBoolean = shaderMaxBooleanConstants;
            }
            maxRegister = -1;

            this.samplers              = new List <InputOutput>();
            this.inputs                = new List <InputOutput>();
            this.outputs               = new List <InputOutput>();
            this.assignedConstants     = new Dictionary <int, bool>();
            this.localConstants        = new Dictionary <int, string>();
            this.localBooleanConstants = new Dictionary <int, string>();
            this.localIntegerConstants = new Dictionary <int, string>();

            for (int i = 0; i < 256; i++)
            {
                assignedConstants.Add(i, false);
            }

            this.source = new StringBuilder();

            this.listing = asmSource;

            if (listing.GetCommandCount() > 0)
            {
                //attempt to decode the shader
                if (DetectProfile())
                {
                    List <Command> commands = new List <Command>();
                    for (int i = 1; i < listing.GetCommandCount(); i++)
                    {
                        //extract the commands
                        Command cmd = new Command(listing.GetCommand(i));
                        if (cmd.name != null)
                        {
                            commands.Add(cmd);
                        }
                    }

                    List <Command> allCommands = new List <Command>();

                    List <Command> newCommands = new List <Command>();
                    foreach (Command command in commands)
                    {
                        newCommands.Clear();
                        GenerateCode(command, newCommands);
                        allCommands.AddRange(newCommands);
                    }
                    commands = allCommands;

                    bool isAsm = false;

                    foreach (Command cmd in commands)
                    {
                        if (cmd.isAsm != isAsm)
                        {
                            if (isAsm)
                            {
                                this.source.Append("};");
                                this.source.AppendLine();
                            }
                            else
                            {
                                this.source.Append("asm{");
                                this.source.AppendLine();
                            }
                            isAsm = cmd.isAsm;
                        }

                        this.source.Append(cmd.name);
                        for (int i = 0; i < cmd.args.Length; i++)
                        {
                            this.source.Append(' ');
                            if (i != 0)
                            {
                                this.source.Append(',');
                            }
                            for (int a = 0; a < cmd.args[i].Length; a++)
                            {
                                this.source.Append(cmd.args[i][a]);
                            }
                        }
                        this.source.AppendLine();
                    }
                    if (isAsm)
                    {
                        this.source.Append("};");
                    }
                }
            }

            BuildMethod();

            CompiledShader shader =
                ShaderCompiler.CompileFromSource(
                    this.source.ToString(),
                    null, null, CompilerOptions.AvoidFlowControl, "Main",
                    profile, platform);

            if (throwOnError && !shader.Success)
            {
                Common.ThrowError("An error occured running the Xbox shader HLSL/ASM preprocessor", shader.ErrorsAndWarnings, asmSource.ToString());
            }

            if (!shader.Success)
            {
                //tried the best.. if it failed, ohh well, go back to AssembleFromSource
                //probably used complex flow control?
                string rawAsm = asmSource.ToString();

                shader = ShaderCompiler.AssembleFromSource(rawAsm, null, null, CompilerOptions.None, platform);

                if (!shader.Success)
                {
                    Common.ThrowError(shader.ErrorsAndWarnings, rawAsm);
                }
            }

            output = shader.GetShaderCode();
        }