예제 #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);
        }
예제 #2
0
 public void MergeSemantics(RegisterSet fxRegisters)
 {
     for (int i = 0; i < this.registers.Length; i++)
     {
         //find the matching reg in the FX registers
         foreach (Register fx in fxRegisters)
         {
             if (fx.Name == this.registers[i].Name)
             {
                 this.registers[i].Semantic = fx.Semantic;
             }
         }
     }
 }
예제 #3
0
        private void MergeSemantics(RegisterSet fxRegisters)
        {
            if (psListing != null)
            {
                this.psListing.RegisterSet.MergeSemantics(fxRegisters);
            }
            if (vsListing != null)
            {
                this.vsListing.RegisterSet.MergeSemantics(fxRegisters);
            }
            if (psPreshaderListing != null)
            {
                this.psPreshaderListing.RegisterSet.MergeSemantics(fxRegisters);
            }
            if (vsPreshaderListing != null)
            {
                this.vsPreshaderListing.RegisterSet.MergeSemantics(fxRegisters);
            }

            this.registers.MergeSemantics(fxRegisters);
        }
		public ShaderRegisters(SourceShader source, string techniqueName, Platform platform, IExtensionStatementProvider extensionStatementProvider)
		{
			AsmTechnique technique = source.GetAsmTechnique(techniqueName, platform);
			this.extensionStatementProvider = extensionStatementProvider;

			vsReg = technique.VertexShader.RegisterSet;
			psReg = technique.PixelShader.RegisterSet;

			if (technique.InstancingShader != null)
				vsInstancingReg = technique.InstancingShader.RegisterSet;
			if (technique.BlendingShader != null)
				vsBlendingReg = technique.BlendingShader.RegisterSet;

			if (technique.TechniqueExtraData != null)
			{
				this.techniqueData = technique.TechniqueExtraData;

				psDefault = technique.TechniqueExtraData.PixelShaderConstants;
				vsDefault = technique.TechniqueExtraData.VertexShaderConstants;

				psBooleanDefault = technique.TechniqueExtraData.PixelShaderBooleanConstants;
				vsBooleanDefault = technique.TechniqueExtraData.VertexShaderBooleanConstants;
			}
		}
		private int MaxSamplers(RegisterSet set)
		{
			int maxSampler = 0;

			for (int i = 0; i < set.RegisterCount; i++)
			{
				Register reg = set.GetRegister(i);
				if (reg.Category == RegisterCategory.Sampler)
					maxSampler = Math.Max(reg.Index, maxSampler);
			}
			return maxSampler;
		}
		public void CompactDuplicateRegisters(RegisterSet set, string setName, string techniqueName)
		{
			List<Register> regList = new List<Register>();
			int reindex = 0;

			//find all registers that are duplicates, validate they are the smae format
			for (int i = 0; i < this.registers.Length; i++)
			{
				Register reg, current = this.registers[i];
				if (set.TryGetRegister(current.Name, out reg))
				{
					//found it, validate it's format.
					if (reg.Category != current.Category)
						throw new CompileException(string.Format("Extension '{0}' in Technique '{1}' redefines Register '{2}' format from '{3}' to '{4}'",
							setName, techniqueName, reg.Name, reg.Category.ToString(), current.Category.ToString()));

					if (reg.Rank < current.Rank)
						throw new CompileException(string.Format("Extension '{0}' in Technique '{1}' redefines Register '{2}' rank from '{3}' to '{4}'",
							setName, techniqueName, reg.Name, reg.Rank.ToString(), current.Rank.ToString()));

					if (reg.Size < current.Size)
						throw new CompileException(string.Format("Extension '{0}' in Technique '{1}' uses a larger Register range for '{2}', size from '{3}' to '{4}'",
							setName, techniqueName, reg.Name, reg.Size.ToString(), current.Size.ToString()));
				}
				else
				{
					current.Index = reindex;
					reindex += current.Size;
					regList.Add(current);
				}
			}
			this.calculatedBooleanRegisters = -1;
			this.calculatedFloatRegisters = -1;
			this.registers = regList.ToArray();


			for (int i = 0; i < this.registers.Length; i++)
			{
				if (this.registers[i].Category != RegisterCategory.Float4 &&
					this.registers[i].Category != RegisterCategory.Integer4)
				{
					throw new CompileException(string.Format("Extension '{0}' in Technique '{1}' cannot define an additional non-float Register that is not used by the base shader, see register '{2}'",
						setName, techniqueName, this.registers[i].Name));
				}
			}
		}
		public void MergeSemantics(RegisterSet fxRegisters)
		{
			for (int i = 0; i < this.registers.Length; i++)
			{
				//find the matching reg in the FX registers
				foreach (Register fx in fxRegisters)
				{
					if (fx.Name == this.registers[i].Name)
						this.registers[i].Semantic = fx.Semantic;
				}
			}
		}
		private static string BuildMapping(AsmTechnique asmTechnique, string extension, RegisterSet set)
		{
			StringBuilder sb = new StringBuilder();

			for (int i = 0; i < set.RegisterCount; i++)
			{
				Register reg = set.GetRegister(i);
				string type = reg.Type;

				string source = "_" + extension + "_";

				switch (reg.Category)
				{
					case RegisterCategory.Boolean:
						source += "b";
						break;
					case RegisterCategory.Float4:
						source += "c";
						switch (reg.Rank)
						{
							case RegisterRank.FloatNx2:
							case RegisterRank.IntNx2:
								type = "float4x2";
								break;
							case RegisterRank.FloatNx3:
							case RegisterRank.IntNx3:
								type = "float4x3";
								break;
							case RegisterRank.FloatNx4:
							case RegisterRank.IntNx4:
								type = "float4x4";
								break;
						}
						break;
					default:
						continue;
				}


				sb.Append("#define ");
				sb.Append(TranslateRegisterName(reg.Name, extension));
				string index = "";
				if (reg.ArraySize > 0)
				{
					index = "(__INDEX__)";
					sb.Append(index);
				}

				sb.Append(" (");

				MapToValue(sb, reg, reg.Index, source, index);

				sb.AppendLine(")");
			}

			return sb.ToString();
		}
		private static void MapRegistersToRenamer(TokenRename rename, RegisterSet set, string extension)
		{
			foreach (Register reg in set)
			{
				if (reg.Category == RegisterCategory.Sampler)
					rename.samplerRemapping.Add(reg.Name, string.Format("_" + extension + "_s{0}", reg.Index));
				else
				{
					if (reg.ArraySize > 0)
						rename.arrayRemapping.Add(reg.Name, TranslateRegisterName(reg.Name, extension));
					else
						rename.registerRemapping.Add(reg.Name, TranslateRegisterName(reg.Name, extension));
				}
			}
		}
예제 #10
0
        public DecompiledEffect(SourceShader source, Platform platform)
        {
            CompilerMacro[] macros = null;
            if (platform == Platform.Xbox)
            {
                macros = XboxCompileMacros;
            }

            CompilerIncludeHandler include = null;
            TargetPlatform         target  = TargetPlatform.Windows;

            this.techniqueDefaults = new Dictionary <string, TechniqueExtraData>();

            if (platform != Platform.Both)
            {
                include = new VFetchIncludeHandler(source.FileName, true);                 //ALWAYS target the PC for the vfetch macro
            }
            else
            {
                include = new VFetchIncludeHandler(source.FileName);                 //Acts as a generic handler
            }
            CompiledEffect compiledEffect = Effect.CompileEffectFromSource(source.ShaderSource, macros, include, source.CompilerOptions, target);

            if (!compiledEffect.Success)
            {
                Common.ThrowError(compiledEffect.ErrorsAndWarnings, source.ShaderSource);
            }

            //now pull the good stuff out.
            using (EffectPool pool = new EffectPool())
                using (Effect effect = new Effect(Graphics.GraphicsDevice, compiledEffect.GetEffectCode(), CompilerOptions.None, pool))
                {
                    Register[]      registers = new Register[effect.Parameters.Count];
                    List <Register> textures  = new List <Register>();

                    for (int i = 0; i < registers.Length; i++)
                    {
                        if (effect.Parameters[i].ParameterType == EffectParameterType.Single ||
                            effect.Parameters[i].ParameterType == EffectParameterType.Int32 ||
                            effect.Parameters[i].ParameterType == EffectParameterType.Bool)
                        {
                            registers[i].Name     = effect.Parameters[i].Name;
                            registers[i].Semantic = effect.Parameters[i].Semantic;
                        }

                        if (effect.Parameters[i].ParameterType >= EffectParameterType.Texture &&
                            effect.Parameters[i].ParameterType <= EffectParameterType.TextureCube)
                        {
                            EffectParameterType type = effect.Parameters[i].ParameterType;
                            if (type == EffectParameterType.Texture1D)
                            {
                                type = EffectParameterType.Texture2D;
                            }

                            registers[i].Name     = effect.Parameters[i].Name;
                            registers[i].Semantic = effect.Parameters[i].Semantic;
                            registers[i].Type     = type.ToString();
                            textures.Add(registers[i]);
                        }
                    }

                    this.effectRegisters = new RegisterSet(registers);
                    this.decompiledAsm   = Effect.Disassemble(effect, false);

                    ExtractEffectDefaults(effect, textures, source, platform);
                }
        }
예제 #11
0
        public AsmListing(string listing, RegisterSet registers)
        {
            this.registers = registers;

            Tokenizer tokens = new Tokenizer(listing, true, false, true);

            List <string>     op       = new List <string>();
            List <AsmCommand> commands = new List <AsmCommand>();
            List <AsmOp>      ops      = new List <AsmOp>();
            string            target   = null;

            while (tokens.NextToken())
            {
                string token = tokens.Token;

                switch (token)
                {
                case "(":                               //this only occurs in preshaders
                    tokens.ReadBlock();
                    ops.Add(new AsmOp(new string[] { tokens.Token }));
                    break;

                case ",":
                    if (op.Count > 0)
                    {
                        ops.Add(new AsmOp(op.ToArray()));
                    }
                    op.Clear();
                    break;

                case "\n":
                case "\r":
                    if (op.Count > 0)
                    {
                        ops.Add(new AsmOp(op.ToArray()));
                    }
                    op.Clear();

                    if (target != null)
                    {
                        commands.Add(new AsmCommand(target, ops.ToArray()));
                    }

                    target = null;
                    ops.Clear();
                    break;

                default:
                    if (target == null)
                    {
                        target = token;
                    }
                    else
                    {
                        op.Add(token);
                    }
                    break;
                }
            }

            this.commands = commands.ToArray();

            this.dclIn  = ExtractInputs();
            this.dclOut = ExtractOuputs();
        }
		public DecompiledEffect(SourceShader source, Platform platform)
		{
			this.techniqueDefaults = new Dictionary<string, TechniqueExtraData>();

			var handler = new EffectHandler();
			handler.source = source.ShaderSource;
			handler.filename = source.FileName;
			handler.buildForXbox = platform == Platform.Xbox;

			//create the native DX decompiler wrapper
			var decompiler = new Native.ShaderDecompiler(ASCIIEncoding.ASCII.GetBytes(source.ShaderSource), source.FileName, platform == Platform.Xbox, handler);
			
			Effect effect = handler.Effect;

			if (decompiler.Errors != null && decompiler.GetShaderCode() == null)
				Common.ThrowError(decompiler.Errors);
			
			//now pull the good stuff out.

			List<Register> registers = new List<Register>();
			List<Register> textures = new List<Register>();

			for (int i = 0; i < effect.Parameters.Count; i++)
			{
				Register register = new Register();

				if (effect.Parameters[i].ParameterType == EffectParameterType.Single ||
					effect.Parameters[i].ParameterType == EffectParameterType.Int32 ||
					effect.Parameters[i].ParameterType == EffectParameterType.Bool)
				{
					register.Name = effect.Parameters[i].Name;
					register.Semantic = effect.Parameters[i].Semantic;
					register.ArraySize = effect.Parameters[i].Elements.Count;
					register.Size = effect.Parameters[i].RowCount * Math.Max(1, register.ArraySize);
					registers.Add(register);
				}

				if (effect.Parameters[i].ParameterType >= EffectParameterType.Texture &&
					effect.Parameters[i].ParameterType <= EffectParameterType.TextureCube)
				{
					EffectParameterType type = effect.Parameters[i].ParameterType;
					if (type == EffectParameterType.Texture1D)
						type = EffectParameterType.Texture2D;

					register.Name = effect.Parameters[i].Name;
					register.Semantic = effect.Parameters[i].Semantic;
					register.Type = type.ToString();
					textures.Add(register);
					register.Category = RegisterCategory.Texture;
					registers.Add(register);
				}

			}

			//iterate the samplers (XNA 4 removed the ability to query samplers!)
			var samplers = decompiler.GetSamplers();
			for (int i = 0; i < samplers.Length; i++)
			{
				var sampler = new Register();
				sampler.Name = samplers[i].Name;
				sampler.Semantic = samplers[i].Semantic;
				sampler.Type = samplers[i].Type;
				sampler.Category = RegisterCategory.Sampler;
				registers.Add(sampler);
			}
			
			//null any empty semantics
			for (int i = 0; i < registers.Count; i++)
			{
				Register reg = registers[i];
				if (reg.Semantic != null && reg.Semantic.Length == 0)
					reg.Semantic = null;
				registers[i] = reg;
			}

			this.effectRegisters = new RegisterSet(registers.ToArray());
			this.decompiledAsm = decompiler.DisassembledCode;

			ExtractEffectDefaults(effect, textures, source, platform);

			effect.Dispose();
			effect = null;
		}
예제 #13
0
		private void MergeSemantics(RegisterSet fxRegisters)
		{
			if (psListing != null)
				this.psListing.RegisterSet.MergeSemantics(fxRegisters);
			if (vsListing != null)
				this.vsListing.RegisterSet.MergeSemantics(fxRegisters);

			this.registers.MergeSemantics(fxRegisters);
		}
예제 #14
0
		private void SetupCommonRegisters()
		{
			Dictionary<string, Register> common = new Dictionary<string, Register>();

			AsmListing[] listings = new AsmListing[] { vsListing, psListing, vsBlendOverride, vsInstancingOverride };

			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);
		}
예제 #15
0
		void CreateRegisterOffsetList(RegisterSet set, string prefix, string postfix, Action<CodeTypeMember, string> add)
		{
			if (set == null)
				return;
			foreach (Register reg in set)
			{
				if (reg.Category == RegisterCategory.Float4 ||
					reg.Category == RegisterCategory.Integer4)
				{
					CodeMemberField field = new CodeMemberField(typeof(int), prefix + Common.ToUpper(reg.Name) + postfix);
					field.Attributes = MemberAttributes.Const | MemberAttributes.Assembly;
					field.InitExpression = new CodePrimitiveExpression(reg.Index);
					add(field, null);
				}
			}
		}
예제 #16
0
		private CodeMemberField CreateShaderBufferField(IShaderDom shader, RegisterSet regSet, string name)
		{
			CodeExpression create = new CodeArrayCreateExpression(typeof(Vector4),
							new CodePrimitiveExpression(regSet.FloatRegisterCount)); //create with the number of registers

			//create the vertex registers
			CodeMemberField field = new CodeMemberField(typeof(Vector4[]), name);
			field.InitExpression = create;
			if (shader.SourceShader.ExposeRegisters)
				field.Attributes = MemberAttributes.Assembly | MemberAttributes.Final;
			else
				field.Attributes = MemberAttributes.Private | MemberAttributes.Final;
			return field;
		}