Example #1
0
        private void CreatRegisters()
        {
            #region Register difine
            Test_mode = new Register("Test_mode", 0xAA, "Test_Mode", 8);
            Test00    = new Register("Test00", 0xF0, "Test_ana_H", 8);
            Test01    = new Register("Test01", 0xF1, "Test_ana_L", 8);
            Test02    = new Register("Test02", 0xF2, "Trim_Sel", 1, "Fuse_en", 1, "Trim_load", 1, "ANA_T", 1, "Norm_T", 1, "LR_sel", 1, "Norm_en", 1, "Fuse_COPY", 1);
            Test03    = new Register("Test03", 0xF3, "Chip_ID_H", 8);
            Test04    = new Register("Test04", 0xF4, "CHip_ID_L", 8);
            Test05    = new Register("Test05", 0xF5, "Gain", 5);
            Test06    = new Register("Test06", 0xF6, "Fuse_Version", 2, "Trim_master", 1);
            SoftReset = new Register("SoftReset", 0xFF, "SoftReset", 8);
            #endregion Register difine

            #region Add all registers to regMap
            ADMP521TRegMap.Add(Test_mode);
            ADMP521TRegMap.Add(Test00);
            ADMP521TRegMap.Add(Test01);
            ADMP521TRegMap.Add(Test02);
            ADMP521TRegMap.Add(Test03);
            ADMP521TRegMap.Add(Test04);
            ADMP521TRegMap.Add(Test05);
            ADMP521TRegMap.Add(Test06);
            ADMP521TRegMap.Add(SoftReset);
            #endregion Add all registers to regMap
        }
Example #2
0
        public void ParseMap(string map)
        {
            string[]    lines  = map.Replace("\r\n", "\n").Split(new char[] { '\n' });
            RadioButton sender = null;

            for (int i = 0; i < lines.Length; i++)
            {
                if (lines[i].Equals(_rowSeparator))
                {
                    _uxNotes.Text = "";
                    for (int j = i + 1; j < lines.Length; j++)
                    {
                        _uxNotes.Text = _uxNotes.Text + lines[j] + "\n";
                    }
                    break;
                }

                string[] strArray2 = lines[i].TrimEnd(new char[] { '\r' }).Split(new char[] { '\t' });

                RadioButton button2 = new RadioButton
                {
                    Name = "rb" + strArray2[0]
                };
                if (i == 0)
                {
                    button2.Checked = true;
                    sender          = button2;
                }

                RegisterSTB rstb = new RegisterSTB();
                rstb.Address      = Convert.ToInt32(strArray2[0], 16);
                rstb.Name         = strArray2[1];
                rstb.Description  = strArray2[2];
                rstb.Comment      = strArray2[5].Replace('|', ' ');
                rstb.BitFieldName = strArray2[6].Split(new char[] { ',' });
                Array.Reverse(rstb.BitFieldName);
                rstb.Type.Value = (RegisterOptions)Convert.ToInt32(strArray2[4]);
                rstb.Type.Rw    = strArray2[3];
                RegisterMap.Add(rstb.Address, rstb);

                button2.Font            = new Font(FontName, (float)RadioButtonFontSize, FontStyle.Regular);
                button2.Text            = string.Format("{0} {1}", strArray2[0], rstb.Name);
                button2.ForeColor       = Color.Black;
                button2.AutoSize        = true;
                button2.CheckedChanged += new EventHandler(rbo_CheckedChanged);
                _uxRbPanel.Controls.Add(button2);
            }
            ButtonExportRegisters           = new Button();
            ButtonExportRegisters.Text      = "Export All Records";
            ButtonExportRegisters.AutoSize  = true;
            ButtonExportRegisters.BackColor = Color.Gray;
            ButtonExportRegisters.ForeColor = Color.Black;
            _uxRbPanel.Controls.Add(ButtonExportRegisters);
            rbo_CheckedChanged(sender, null);
        }
Example #3
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());;
        }
		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();;
		}
Example #5
0
        /// <summary>
        /// Create regmap from local excel data without bitfield
        /// </summary>
        /// <param name="_dsExcel"></param>
        private RegisterMap CreateRegMap(DataSet _dsExcel)
        {
            RegisterMap _regmap = new RegisterMap();

            ds_display.Clear();
            DataTable dt = _dsExcel.Tables[regmapName];

            // Get Device Address
            if (dt.Rows[0][0].ToString().ToUpper() == devAddrName)
            {
                this.devAddr    = Convert.ToUInt32(dt.Rows[0][1].ToString().TrimStart("7'b".ToCharArray()), 2);
                _regmap.DevAddr = devAddr;
            }

            // judge if this is a crazy mode reg map, if crazy mode, then there is one more column for num. of bytes of 1 register
            if (dt.Rows[0][2].ToString().ToUpper() == devRegMode)
            {
                if (dt.Rows[0][3].ToString().ToUpper() == "CRAZY")
                {
                    crazyMode = true;
                }
            }

            DataRowCollection drc = dt.Rows;
            int    rowsCount      = dt.Rows.Count;
            string regGroup       = "";
            string regName        = "";
            string regAddr        = "";
            string numOfBytes     = "";
            string defaultValue   = "";

            object[]      items;
            List <object> temp_bf = new List <object> {
            };
            int valid_count       = 0;

            RWProperty rw = RWProperty.RW;

            for (int ix = 2; ix < rowsCount;)
            {
                #region normal register map
                if (!crazyMode)
                {
                    // New reg group generated here
                    if (drc[ix].ItemArray[(int)itemIx.regGroup].ToString() != "")
                    {
                        regGroup = drc[ix].ItemArray[(int)itemIx.regGroup].ToString().Replace("\n", "");
                        _regmap.AddGroup(regGroup);
                    }

                    // Get all valid bit field name and store in a long array
                    items       = drc[ix++].ItemArray;
                    valid_count = 0;
                    temp_bf.Clear();
                    for (int bit_ix = (int)itemIx.bit7; bit_ix <= (int)itemIx.bit0; bit_ix++)
                    {
                        if (items[bit_ix].ToString() != "")
                        {
                            valid_count++;
                            temp_bf.Add(items[bit_ix]);
                        }
                    }

                    if (valid_count == 0)
                    {
                        continue;
                    }

                    // copy the true valid bit field name to new bitfield name array
                    object[] bfs = new object[valid_count];
                    for (int bf_ix = 0; bf_ix < valid_count; bf_ix++)
                    {
                        bfs[bf_ix] = temp_bf[bf_ix];
                    }

                    if (items[(int)itemIx.rw].ToString() == "R")
                    {
                        rw = RWProperty.R;
                    }
                    else if (items[3].ToString() == "W")
                    {
                        rw = RWProperty.W;
                    }
                    else
                    {
                        rw = RWProperty.RW;
                    }

                    _regmap.Add(new Register(regGroup, items[(int)itemIx.regName].ToString(), items[(int)itemIx.regAddr].ToString(), rw, items[(int)itemIx.defaultRegValue].ToString(), bfs));
                }
                #endregion

                #region  crazy register map mode
                else
                {
                    // New reg group generated here
                    if (drc[ix].ItemArray[(int)itemIx_Crazy.regGroup].ToString() != "")
                    {
                        regGroup = drc[ix].ItemArray[(int)itemIx_Crazy.regGroup].ToString().Replace("\n", "");
                        _regmap.AddGroup(regGroup);
                    }

                    // New Reg start from here, get regName, regAddr and number of bytes
                    if (drc[ix].ItemArray[(int)itemIx_Crazy.regName].ToString() != "")
                    {
                        regName      = drc[ix].ItemArray[(int)itemIx_Crazy.regName].ToString();
                        regAddr      = drc[ix].ItemArray[(int)itemIx_Crazy.regAddr].ToString();
                        numOfBytes   = drc[ix].ItemArray[(int)itemIx_Crazy.byteCount].ToString();
                        defaultValue = drc[ix].ItemArray[(int)itemIx_Crazy.defaultRegValue].ToString();
                    }

                    if (regName.ToUpper() == "RESERVED")
                    {
                        ix++;
                        continue;
                    }

                    // Get all valid bit field name and store in a long array
                    temp_bf.Clear();
                    valid_count = 0;
                    do
                    {
                        items = drc[ix].ItemArray;
                        for (int bit_ix = (int)itemIx_Crazy.bit7; bit_ix <= (int)itemIx_Crazy.bit0; bit_ix++)
                        {
                            if (items[bit_ix].ToString() != "" && items[bit_ix].ToString().ToUpper() != "RESERVED")
                            {
                                valid_count++;
                                temp_bf.Add(items[bit_ix]);
                            }
                        }
                    } while ((++ix < rowsCount) && (drc[ix].ItemArray[(int)itemIx_Crazy.regName].ToString() == ""));

                    // copy the true valid bit field name to new bitfield name array
                    object[] bfs = new object[valid_count];
                    for (int bf_ix = 0; bf_ix < valid_count; bf_ix++)
                    {
                        bfs[bf_ix] = temp_bf[bf_ix];
                    }

                    if (items[(int)itemIx_Crazy.rw].ToString() == "R")
                    {
                        rw = RWProperty.R;
                    }
                    else if (items[3].ToString() == "W")
                    {
                        rw = RWProperty.W;
                    }
                    else
                    {
                        rw = RWProperty.RW;
                    }

                    _regmap.Add(new Register(regGroup, regName, regAddr, rw, numOfBytes, defaultValue, bfs));
                }
                #endregion
            }

            return(_regmap);
        }
		public static string ConvertToGLSL (ByteArray agal)
		{
			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 0x17: // m33
					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?
					break;
				case 0x18: // m44
					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);
					break;
				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 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 0x12: // dp3
					sr1.sourceMask = sr2.sourceMask = 7; // adjust dest 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 dest 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 0x8: // frc
					sb.AppendFormat("{0} = fract({1}); // frc", 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 0x0E: // normalize
					sb.AppendFormat("{0} = normalize({1}); // normalize", dr.ToGLSL(), sr1.ToGLSL() ); 
					map.Add(dr, RegisterUsage.Vector4);
					map.Add(sr1, RegisterUsage.Vector4);
					break;

				case 0x27: // kill /  discard
					sb.AppendFormat("// if ({0} > 0.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);
					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));
			glsl.AppendLine("void main() {");
			glsl.Append (map.ToGLSL(true));
			glsl.Append(sb.ToString());
			glsl.AppendLine("}");
			System.Console.WriteLine(glsl);
			return glsl.ToString();;
		}