Exemplo n.º 1
0
        private string GetSrcReg(ShaderProgram Program, uint Reg, uint Idx = 0)
        {
            if (Reg >= 0x20 && Reg < 0x80)
            {
                ShaderUniformVec4 Uniform = Program.Vec4Uniforms[Reg - 0x20];

                string Name = Vec4UniformNames[Reg - 0x20];

                if (Uniform.IsConstant)
                {
                    return(string.Format(CultureInfo.InvariantCulture, "vec4({0}, {1}, {2}, {3})",
                                         Uniform.Constant.X,
                                         Uniform.Constant.Y,
                                         Uniform.Constant.Z,
                                         Uniform.Constant.W));
                }
                else if (Uniform.IsArray && Idx > 0)
                {
                    //Min protects against illegal accesses (can cause glitches on some GPUs).
                    Name = Vec4UniformNamesNoIdx[Reg - 0x20];

                    int Max = Uniform.ArrayLength - 1;

                    switch (Idx)
                    {
                    case 1: return($"{Name}[min({Uniform.ArrayIndex} + {A0RegName}.x, {Max})]");

                    case 2: return($"{Name}[min({Uniform.ArrayIndex} + {A0RegName}.y, {Max})]");

                    case 3: return($"{Name}[min({Uniform.ArrayIndex} + {ALRegName}, {Max})]");
                    }
                }

                return(Name);
            }
            else if (Reg < 0x10)
            {
                return(InputNames[Reg]);
            }
            else if (Reg < 0x20)
            {
                return($"{TempRegName}[{Reg - 0x10}]");
            }
            else
            {
                throw new InvalidOperationException($"Invalid register Index {Reg} used!");
            }
        }
Exemplo n.º 2
0
        private void GenVec4Uniforms(StringBuilder Output, ShaderUniformVec4[] Uniforms, string[] Names, string Type)
        {
            for (int i = 0; i < Uniforms.Length; i++)
            {
                ShaderUniformVec4 Uniform = Uniforms[i];

                if (Uniform?.IsConstant ?? true)
                {
                    continue;
                }

                string Name = $"{Type}_{i - Uniform.ArrayIndex}_{GetValidName(Uniform.Name)}";

                /*
                 * For registers used as arrays, the name is stored with the
                 * indexer ([0], [1], [2]...), but a version without the indexer
                 * is also stored in Vec4UniformNamesNoIdx for GetSrcReg func, since it
                 * needs indexed array access with illegal memory access protection.
                 */
                string Indexer = Uniform.IsArray ? $"[{Uniform.ArrayIndex}]" : string.Empty;

                Names[i] = Name + Indexer;

                if (Names == Vec4UniformNames)
                {
                    Vec4UniformNamesNoIdx[i] = Name;
                }

                if (Uniform.ArrayIndex == 0)
                {
                    if (Uniform.IsArray)
                    {
                        Output.AppendLine($"uniform {Type} {Name}[{Uniform.ArrayLength}];");
                    }
                    else
                    {
                        Output.AppendLine($"uniform {Type} {Name};");
                    }
                }
            }
        }
Exemplo n.º 3
0
        private void GenLoop(ShaderProgram Program, ShaderInst3 Inst)
        {
            ShaderUniformVec4 Uniform = Program.IVec4Uniforms[Inst.RegId & 3];

            string IUName = IVec4UniformNames[Inst.RegId & 3];

            string ALStart;
            string ALCond;
            string ALInc;

            if (Uniform.IsConstant)
            {
                ALStart = $"{ALRegName} = {(byte)Uniform.Constant.Y}";
                ALCond  = $"{ALRegName} <= {(byte)Uniform.Constant.X}";
                ALInc   = $"{ALRegName} += {(byte)Uniform.Constant.Z}";
            }
            else
            {
                ALStart = $"{ALRegName} = {IUName}.y";
                ALCond  = $"{ALRegName} <= {IUName}.x";
                ALInc   = $"{ALRegName} += {IUName}.z";
            }

            Append($"for ({ALStart}; {ALCond}; {ALInc}) {{");

            string OldIdent = Ident;

            Ident += "\t";

            while (IP + 1 <= Inst.Dest)
            {
                GenInst(Program, SHBin.Executable[++IP]);
            }

            Ident = OldIdent;

            Append("}");
        }