Esempio n. 1
0
        public override void FlushText(StreamWriter aSW)
        {
            string des = DestinationReg.HasValue ? DestinationReg.ToString() : DestinationRef;
            string src = SourceReg.HasValue ? SourceReg.ToString() : SourceRef;

            if (DestinationDisplacement > 0)
            {
                des = des + " + 0x" + ((uint)DestinationDisplacement).ToString("X");
            }
            else if (DestinationDisplacement < 0)
            {
                des = des + " - 0x" + ((int)(-1 * DestinationDisplacement)).ToString("X");
            }

            if (SourceDisplacement > 0)
            {
                src = src + " + 0x" + ((uint)SourceDisplacement).ToString("X");
            }
            else if (SourceDisplacement < 0)
            {
                src = src + " - 0x" + ((int)(-1 * SourceDisplacement)).ToString("X");
            }

            if (DestinationIndirect)
            {
                des = "[" + des + "]";
            }

            if (SourceIndirect)
            {
                src = "[" + src + "]";
            }

            aSW.WriteLine(string.Format("{0} {1}, {2}, 0x{3}", Code, des, src, ((byte)PseudoCode).ToString("X")));
        }
Esempio n. 2
0
 public RegisterUsage GetUsage(SourceReg sr)
 {
     if (sr.d != 0)
     {
         return(RegisterUsage.Vector4Array);
     }
     return(GetUsage(sr.type, sr.ToGLSL(false), sr.n));
 }
Esempio n. 3
0
 public void Add(SourceReg sr, RegisterUsage usage, int offset = 0)
 {
     if (sr.d != 0)
     {
         Add(sr.itype, PrefixFromType(sr.itype, sr.programType) + sr.n.ToString(), sr.n, RegisterUsage.Vector4);
         Add(sr.type, PrefixFromType(sr.type, sr.programType) + sr.o.ToString(), sr.o, RegisterUsage.Vector4Array);
         return;
     }
     Add(sr.type, sr.ToGLSL(false, offset), sr.n + offset, usage);
 }
Esempio n. 4
0
            public static SourceReg Parse(ulong v, ProgramType programType, int sourceMask)
            {
                var sr = new SourceReg();

                sr.programType = programType;
                sr.d           = (int)((v >> 63) & 1);       //  Direct=0/Indirect=1 for direct Q and I are ignored, 1bit
                sr.q           = (int)((v >> 48) & 0x3);     // index register component select
                sr.itype       = (int)((v >> 40) & 0xF);     // index register type
                sr.type        = (RegType)((v >> 32) & 0xF); // type
                sr.s           = (int)((v >> 24) & 0xFF);    // swizzle
                sr.o           = (int)((v >> 16) & 0xFF);    // indirect offset
                sr.n           = (int)(v & 0xFFFF);          // number
                sr.sourceMask  = sourceMask;
                return(sr);
            }
Esempio n. 5
0
        public static string ConvertToGLSL(ByteArray agal, textures.SamplerState[] outSamplers)
        {
            agal.position = 0;

            int magic = agal.readByte();

            if (magic != 0xA0)
            {
                throw new InvalidOperationException("Magic value must be 0xA0, may not be AGAL");
            }

            int version = agal.readInt();

            if (version != 1)
            {
                throw new InvalidOperationException("Version must be 1");
            }

            int shaderTypeId = agal.readByte();

            if (shaderTypeId != 0xA1)
            {
                throw new InvalidOperationException("Shader type id must be 0xA1");
            }

            ProgramType programType = (agal.readByte() == 0) ? ProgramType.Vertex : ProgramType.Fragment;

            var map = new RegisterMap();
            var sb  = new StringBuilder();

            while (agal.position < agal.length)
            {
                // fetch instruction info
                int   opcode  = agal.readInt();
                uint  dest    = (uint)agal.readInt();
                ulong source1 = ReadUInt64(agal);
                ulong source2 = ReadUInt64(agal);
//				sb.Append("\t");
//				sb.AppendFormat("// opcode:{0:X} dest:{1:X} source1:{2:X} source2:{3:X}\n", opcode,
//				                dest, source1, source2);

                // parse registers
                var dr  = DestReg.Parse(dest, programType);
                var sr1 = SourceReg.Parse(source1, programType, dr.mask);
                var sr2 = SourceReg.Parse(source2, programType, dr.mask);

                // switch on opcode and emit GLSL
                sb.Append("\t");
                switch (opcode)
                {
                case 0x00:                 // mov
                    sb.AppendFormat("{0} = {1}; // mov", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x01:                 // add
                    sb.AppendFormat("{0} = {1} + {2}; // add", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x02:                 // sub
                    sb.AppendFormat("{0} = {1} - {2}; // sub", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x03:                 // mul
                    sb.AppendFormat("{0} = {1} * {2}; // mul", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x04:                 // div
                    sb.AppendFormat("{0} = {1} / {2}; // div", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x05:                 // rcp
                    sb.AppendFormat("{0} = vec4(1) / {1}; // rcp (untested)", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x06:                 // min
                    sb.AppendFormat("{0} = min({1}, {2}); // min", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x07:                 // max
                    sb.AppendFormat("{0} = max({1}, {2}); // max", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x08:                 // frc
                    sb.AppendFormat("{0} = fract({1}); // frc", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x09:                 // sqrt
                    sb.AppendFormat("{0} = sqrt({1}); // sqrt", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x0A:                 // rsq
                    sb.AppendFormat("{0} = inversesqrt({1}); // rsq", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x0B:                 // pow
                    sb.AppendFormat("{0} = pow({1}, {2}); // pow", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x0C:                 // log
                    sb.AppendFormat("{0} = log2({1}); // log", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x0D:                 // exp
                    sb.AppendFormat("{0} = exp2({1}); // exp", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x0E:                 // normalize
                    sb.AppendFormat("{0} = normalize({1}); // normalize", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x0F:                 // sin
                    sb.AppendFormat("{0} = sin({1}); // sin", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x10:                 // cos
                    sb.AppendFormat("{0} = cos({1}); // cos", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x11:                               // crs
                    sr1.sourceMask = sr2.sourceMask = 7; // adjust source mask for xyz input to dot product
                    sb.AppendFormat("{0} = cross(vec3({1}), vec3({2})); // crs", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x12:                               // dp3
                    sr1.sourceMask = sr2.sourceMask = 7; // adjust source mask for xyz input to dot product
                    sb.AppendFormat("{0} = dot(vec3({1}), vec3({2})); // dp3", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x13:                                 // dp4
                    sr1.sourceMask = sr2.sourceMask = 0xF; // adjust source mask for xyzw input to dot product
                    sb.AppendFormat("{0} = dot(vec4({1}), vec4({2})); // dp4", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x14:                 // abs
                    sb.AppendFormat("{0} = abs({1}); // abs", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x15:                 // neg
                    sb.AppendFormat("{0} = -{1}; // neg", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x16:                 // saturate
                    sb.AppendFormat("{0} = clamp({1}, 0.0, 1.0); // saturate", dr.ToGLSL(), sr1.ToGLSL());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x17:                 // m33
                {
                    var existingUsage = map.GetUsage(sr2);
                    if (existingUsage != RegisterUsage.Vector4)
                    {
                        sb.AppendFormat("{0} = {1} * mat3({2}); // m33", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL(false));
                        map.Add(dr, RegisterUsage.Vector4);
                        map.Add(sr1, RegisterUsage.Vector4);
                        map.Add(sr2, RegisterUsage.Matrix44);                         // 33?
                    }
                    else
                    {
                        // compose the matrix multiply from dot products
                        sr1.sourceMask = sr2.sourceMask = 7;
                        sb.AppendFormat("{0} = vec3(dot({1},{2}), dot({1},{3}), dot({1},{4})); // m33", dr.ToGLSL(), sr1.ToGLSL(true),
                                        sr2.ToGLSL(true, 0),
                                        sr2.ToGLSL(true, 1),
                                        sr2.ToGLSL(true, 2)
                                        );

                        map.Add(dr, RegisterUsage.Vector4);
                        map.Add(sr1, RegisterUsage.Vector4);
                        map.Add(sr2, RegisterUsage.Vector4, 0);
                        map.Add(sr2, RegisterUsage.Vector4, 1);
                        map.Add(sr2, RegisterUsage.Vector4, 2);
                    }
                }
                break;

                case 0x18:                 // m44
                {
                    var existingUsage = map.GetUsage(sr2);
                    if (existingUsage != RegisterUsage.Vector4)
                    {
                        sb.AppendFormat("{0} = {1} * {2}; // m44", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL(false));
                        map.Add(dr, RegisterUsage.Vector4);
                        map.Add(sr1, RegisterUsage.Vector4);
                        map.Add(sr2, RegisterUsage.Matrix44);
                    }
                    else
                    {
                        // compose the matrix multiply from dot products
                        sr1.sourceMask = sr2.sourceMask = 0xF;
                        sb.AppendFormat("{0} = vec4(dot({1},{2}), dot({1},{3}), dot({1},{4}, dot({1},{5})); // m44", dr.ToGLSL(), sr1.ToGLSL(true),
                                        sr2.ToGLSL(true, 0),
                                        sr2.ToGLSL(true, 1),
                                        sr2.ToGLSL(true, 2),
                                        sr2.ToGLSL(true, 3)
                                        );

                        map.Add(dr, RegisterUsage.Vector4);
                        map.Add(sr1, RegisterUsage.Vector4);
                        map.Add(sr2, RegisterUsage.Vector4, 0);
                        map.Add(sr2, RegisterUsage.Vector4, 1);
                        map.Add(sr2, RegisterUsage.Vector4, 2);
                        map.Add(sr2, RegisterUsage.Vector4, 3);
                    }
                }
                break;

                case 0x19:                 // m34
                {
                    // prevent w from being written for a m34
                    dr.mask &= 7;

                    var existingUsage = map.GetUsage(sr2);
                    if (existingUsage != RegisterUsage.Vector4)
                    {
                        sb.AppendFormat("{0} = {1} * {2}; // m34", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL(false));
                        map.Add(dr, RegisterUsage.Vector4);
                        map.Add(sr1, RegisterUsage.Vector4);
                        map.Add(sr2, RegisterUsage.Matrix44);
                    }
                    else
                    {
                        // compose the matrix multiply from dot products
                        sr1.sourceMask = sr2.sourceMask = 0xF;
                        sb.AppendFormat("{0} = vec3(dot({1},{2}), dot({1},{3}), dot({1},{4}); // m34", dr.ToGLSL(), sr1.ToGLSL(true),
                                        sr2.ToGLSL(true, 0),
                                        sr2.ToGLSL(true, 1),
                                        sr2.ToGLSL(true, 2)
                                        );

                        map.Add(dr, RegisterUsage.Vector4);
                        map.Add(sr1, RegisterUsage.Vector4);
                        map.Add(sr2, RegisterUsage.Vector4, 0);
                        map.Add(sr2, RegisterUsage.Vector4, 1);
                        map.Add(sr2, RegisterUsage.Vector4, 2);
                    }
                }
                break;

                case 0x27:                 // kill /  discard
                    sb.AppendFormat("if (any(lessThan({0}, vec4(0)))) discard;", sr1.ToGLSL());
                    map.Add(sr1, RegisterUsage.Vector4);
                    break;

                case 0x28:                 // tex
                    SamplerReg sampler = SamplerReg.Parse(source2, programType);

                    switch (sampler.d)
                    {
                    case 0:                     // 2d texture
                        sr1.sourceMask = 0x3;
                        sb.AppendFormat("{0} = texture2D({2}, {1}); // tex", dr.ToGLSL(), sr1.ToGLSL(), sampler.ToGLSL());
                        map.Add(sampler, RegisterUsage.Sampler2D);
                        break;

                    case 1:                     // cube texture
                        sr1.sourceMask = 0x7;
                        sb.AppendFormat("{0} = textureCube({2}, {1}); // tex", dr.ToGLSL(), sr1.ToGLSL(), sampler.ToGLSL());
                        map.Add(sampler, RegisterUsage.SamplerCube);
                        break;
                    }
                    //sb.AppendFormat("{0} = vec4(0,1,0,1);", dr.ToGLSL() );
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);

                    if (outSamplers != null)
                    {
                        // add sampler state to output list for caller
                        outSamplers[sampler.n] = sampler.ToSamplerState();
                    }
                    break;

                case 0x29:                                 // sge
                    sr1.sourceMask = sr2.sourceMask = 0xF; // sge only supports vec4
                    sb.AppendFormat("{0} = vec4(greaterThanEqual({1}, {2})){3}; // ste", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL(), dr.GetWriteMask());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x2A:                                 // slt
                    sr1.sourceMask = sr2.sourceMask = 0xF; // slt only supports vec4
                    sb.AppendFormat("{0} = vec4(lessThan({1}, {2})){3}; // slt", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL(), dr.GetWriteMask());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x2C:                                 // seq
                    sr1.sourceMask = sr2.sourceMask = 0xF; // seq only supports vec4
                    sb.AppendFormat("{0} = vec4(equal({1}, {2})){3}; // seq", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL(), dr.GetWriteMask());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                case 0x2D:                                 // sne
                    sr1.sourceMask = sr2.sourceMask = 0xF; // sne only supports vec4
                    sb.AppendFormat("{0} = vec4(notEqual({1}, {2})){3}; // sne", dr.ToGLSL(), sr1.ToGLSL(), sr2.ToGLSL(), dr.GetWriteMask());
                    map.Add(dr, RegisterUsage.Vector4);
                    map.Add(sr1, RegisterUsage.Vector4);
                    map.Add(sr2, RegisterUsage.Vector4);
                    break;

                default:
                    //sb.AppendFormat ("unsupported opcode" + opcode);
                    throw new NotSupportedException("Opcode " + opcode);
                }

                sb.AppendLine();
            }


#if PLATFORM_MONOMAC
            var glslVersion = 120;
#elif PLATFORM_MONOTOUCH
            var glslVersion = 100;             // Actually this is glsl 1.20 but in gles it's 1.0
#endif

            // combine parts into final progam
            var glsl = new StringBuilder();
            glsl.AppendFormat("// AGAL {0} shader\n", (programType == ProgramType.Vertex) ? "vertex" : "fragment");
            glsl.AppendFormat("#version {0}\n", glslVersion);
#if PLATFORM_MONOTOUCH
            // Required to set the default precision of vectors
            glsl.Append("precision mediump float;\n");
#endif
            glsl.Append(map.ToGLSL(false));
            if (programType == ProgramType.Vertex)
            {
                // this is needed for flipping render textures upside down
                glsl.AppendLine("uniform vec4 vcPositionScale;");
            }
            glsl.AppendLine("void main() {");
            glsl.Append(map.ToGLSL(true));
            glsl.Append(sb.ToString());

            if (programType == ProgramType.Vertex)
            {
                // this is needed for flipping render textures upside down
                glsl.AppendLine("gl_Position *= vcPositionScale;");
            }
            glsl.AppendLine("}");
            // System.Console.WriteLine(glsl);
            return(glsl.ToString());;
        }
Esempio n. 6
0
 public void Add(SourceReg sr, RegisterUsage usage, int offset = 0)
 {
     Add(sr.type, sr.ToGLSL(false, offset), sr.n + offset, usage);
 }
Esempio n. 7
0
 public RegisterUsage GetUsage(SourceReg sr)
 {
     return(GetUsage(sr.type, sr.ToGLSL(false), sr.n));
 }
Esempio n. 8
0
			public void Add(SourceReg sr, RegisterUsage usage, int offset  = 0)
			{
				Add (sr.type, sr.ToGLSL(false, offset), sr.n + offset, usage);
			}
Esempio n. 9
0
			public RegisterUsage GetUsage(SourceReg sr)
			{
				return GetUsage(sr.type, sr.ToGLSL(false), sr.n);
			}
Esempio n. 10
0
			public static SourceReg Parse (ulong v, ProgramType programType, int sourceMask)
			{
				var sr = new SourceReg();
				sr.programType = programType;
				sr.d = (int)((v >> 63) & 1); //  Direct=0/Indirect=1 for direct Q and I are ignored, 1bit
				sr.q = (int)((v >> 48) & 0x3); // index register component select
				sr.itype = (int)((v >> 40) & 0xF); // index register type
				sr.type = (RegType)((v >> 32) & 0xF); // type
				sr.s = (int)((v >> 24) & 0xFF); // swizzle
				sr.o = (int)((v >> 16) & 0xFF);  // indirect offset
				sr.n = (int)(v & 0xFFFF);		// number
				sr.sourceMask = sourceMask;
				return sr;
			}
Esempio n. 11
0
			public void Add(SourceReg sr, RegisterUsage usage, int offset  = 0)
			{
				if (sr.d != 0) {
					Add (sr.type, PrefixFromType(sr.type, sr.programType) + sr.n.ToString(), sr.n, RegisterUsage.Vector4Array);
					return;
				}
				Add (sr.type, sr.ToGLSL(false, offset), sr.n + offset, usage);
			}
Esempio n. 12
0
			public RegisterUsage GetUsage(SourceReg sr)
			{
				if (sr.d != 0) {
					return RegisterUsage.Vector4Array;
				}
				return GetUsage(sr.type, sr.ToGLSL(false), sr.n);
			}
Esempio n. 13
0
			public void Add(SourceReg sr, RegisterUsage usage)
			{
				Add (sr.type, sr.ToGLSL(false), sr.n, usage);
			}