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); }
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 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)); } } }
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); } }
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; }
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); }
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); }
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); } } }
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; }