private void PrepareConstantBuffers(Shader shader) { // Recalculate constant buffers // Order first all non-method declarations and then after method declarations var otherNodes = shader.Declarations.Where(declaration => !(declaration is MethodDeclaration) && !(declaration is Variable)).ToList(); var declarations = new List<Node>(); var variables = shader.Declarations.OfType<Variable>(); var methods = shader.Declarations.OfType<MethodDeclaration>(); var newVariables = new List<Node>(); var constantBuffers = new Dictionary<string, ConstantBuffer>(); foreach (var variableGroup in variables) { foreach (var variable in variableGroup.Instances()) { var constantBufferName = (string)variable.GetTag(XenkoTags.ConstantBuffer); var type = variable.Type; if (type is ArrayType) { var arrayType = (ArrayType)type; type = arrayType.Type; } // Put variable which are not in a constant buffer into one named "Globals". // static variables should stay out of this buffer if (constantBufferName == null && !(type.ResolveType() is ObjectType) && !variable.Qualifiers.Contains(StorageQualifier.Const) && !variable.Qualifiers.Contains(SiliconStudio.Shaders.Ast.Hlsl.StorageQualifier.Static) && !variable.Qualifiers.Contains(SiliconStudio.Shaders.Ast.Hlsl.StorageQualifier.Groupshared)) { constantBufferName = "Globals"; } if (constantBufferName == null) { //declarations.Insert(0, variable); // keep thes kinds of variable at the top of the declaration declarations.Add(variable); } else { // Remove initial value (it should be part of key definition) if (!variable.Qualifiers.Contains(StorageQualifier.Const) && variable.InitialValue != null) variable.InitialValue = null; ConstantBuffer constantBuffer; if (!constantBuffers.TryGetValue(constantBufferName, out constantBuffer)) { constantBuffer = new ConstantBuffer {Name = constantBufferName, Type = SiliconStudio.Shaders.Ast.Hlsl.ConstantBufferType.Constant}; constantBuffers.Add(constantBufferName, constantBuffer); newVariables.Add(constantBuffer); } constantBuffer.Members.Add(variable); } } } declarations.AddRange(otherNodes); declarations.AddRange(newVariables); declarations.AddRange(methods); shader.Declarations = declarations; }
public override void Visit(ConstantBuffer constantBuffer) { // Flatten the constant buffers if (constantBuffer.Members.Count > 0) { if (GenerateUniformBlocks) { Write(constantBuffer.Qualifiers, true); if (constantBuffer.Register != null) { if (constantBuffer.Qualifiers != Qualifier.None) throw new NotImplementedException(); Write("layout(binding = ").Write(constantBuffer.Register.Register.Text).Write(") "); } Write("uniform").Write(" ").Write(constantBuffer.Name).WriteSpace().Write("{").WriteLine(); Indent(); VisitDynamicList(constantBuffer.Members); } else { Write("// Begin cbuffer ").Write(constantBuffer.Name).WriteLine(); foreach (var member in constantBuffer.Members) { // Prefix each variable with "uniform " if (member is Variable) { Write("uniform"); Write(" "); } VisitDynamic(member); } } if (GenerateUniformBlocks) { Outdent(); Write("};").WriteLine(); } else { Write("// End buffer ").Write(constantBuffer.Name).WriteLine(); } } }
protected void Visit(ConstantBuffer constantBuffer) { foreach (var variable in constantBuffer.Members.OfType<Variable>().SelectMany(x => x.Instances())) { ParseConstantBufferVariable(constantBuffer.Name, variable); } }
public void Visit(ConstantBuffer constantBuffer) { currentConstantBuffer = constantBuffer; Visit((Node)constantBuffer); currentConstantBuffer = null; }
// Group everything by constant buffers private void GroupByConstantBuffer() { MergeSameSemanticVariables(mainModuleMixin.ClassReferences.VariablesReferences.Select(x => x.Key).ToList()); MergeReferenceVariables(mainModuleMixin.ClassReferences.VariablesReferences.Select(x => x.Key).ToList()); var usefulVars = mainModuleMixin.ClassReferences.VariablesReferences.Select(x => x.Key).Where(KeepVariableInCBuffer); var varList = usefulVars.Where(x => x.ContainsTag(XenkoTags.ConstantBuffer)).ToList(); var groupedVarList = varList.GroupBy(x => x.GetTag(XenkoTags.ConstantBuffer) as string).Select(x => x.ToList()).ToList(); foreach (var group in groupedVarList) { var cbufferName = group.FirstOrDefault().GetTag(XenkoTags.ConstantBuffer) as string; var cbuffer = new ConstantBuffer { Type = SiliconStudio.Shaders.Ast.Hlsl.ConstantBufferType.Constant, Name = cbufferName }; cbuffer.Members.AddRange(group); MixedShader.Members.Add(cbuffer); } var remainingVars = usefulVars.Where(x => !x.ContainsTag(XenkoTags.ConstantBuffer)).ToList(); var globalBuffer = new ConstantBuffer { Type = SiliconStudio.Shaders.Ast.Hlsl.ConstantBufferType.Constant, Name = "Globals" }; if (remainingVars.Count > 0) { globalBuffer.Members.AddRange(remainingVars); MixedShader.Members.Add(globalBuffer); } // add textures, samplers etc. MixedShader.Members.AddRange(mainModuleMixin.ClassReferences.VariablesReferences.Select(x => x.Key).Where(IsOutOfCBufferVariable)); }
public override void Visit(ConstantBuffer constantBuffer) { currentConstantBuffer = constantBuffer; base.Visit(constantBuffer); currentConstantBuffer = null; }
/// <summary> /// Visits the specified constant buffer. /// </summary> /// <param name="constantBuffer">The constant buffer.</param> public override void Visit(ConstantBuffer constantBuffer) { Write(constantBuffer.Attributes, true); Write(constantBuffer.Type.Key.ToString()); if (constantBuffer.Name != null) { Write(" ").Write(constantBuffer.Name); } WriteSpace(); VisitDynamic(constantBuffer.Register); OpenBrace(); VisitList(constantBuffer.Members); CloseBrace(false).Write(";").WriteLine(); }
/// <inheritdoc/> public override void Visit(ConstantBuffer constantBuffer) { // Flatten the constant buffers if (constantBuffer.Members.Count > 0) { if (GenerateUniformBlocks) { if (constantBuffer.Register != null) { var layoutQualifier = constantBuffer.Qualifiers.OfType<LayoutQualifier>().FirstOrDefault(); if (layoutQualifier == null) { layoutQualifier = new SiliconStudio.Shaders.Ast.Glsl.LayoutQualifier(); constantBuffer.Qualifiers |= layoutQualifier; } layoutQualifier.Layouts.Insert(0, new LayoutKeyValue("binding", constantBuffer.Register.Register)); } Write(constantBuffer.Qualifiers, true); Write("uniform").Write(" ").Write(constantBuffer.Name).WriteSpace().Write("{").WriteLine(); Indent(); VisitList(constantBuffer.Members); } else { Write("// Begin cbuffer ").Write(constantBuffer.Name).WriteLine(); foreach (var member in constantBuffer.Members) { // Prefix each variable with "uniform " if (member is Variable) { Write("uniform"); Write(" "); } VisitDynamic(member); } } if (GenerateUniformBlocks) { Outdent(); Write("};").WriteLine(); } else { Write("// End buffer ").Write(constantBuffer.Name).WriteLine(); } } }
// Group everything by constant buffers private void GroupByConstantBuffer() { MergeSameSemanticVariables(mainModuleMixin.ClassReferences.VariablesReferences.Select(x => x.Key).ToList()); MergeReferenceVariables(mainModuleMixin.ClassReferences.VariablesReferences.Select(x => x.Key).ToList()); // Order variables by cbuffer/rgroup (which still include logical group) var variables = mainModuleMixin.ClassReferences.VariablesReferences.OrderBy(x => ((ConstantBuffer)x.Key.GetTag(XenkoTags.ConstantBuffer))?.Name.Text).ToList(); // Recreate cbuffer with proper logical groups var constantBuffers = new List<ConstantBuffer>(); foreach (var variable in variables) { var cbuffer = (ConstantBuffer)variable.Key.GetTag(XenkoTags.ConstantBuffer); if (cbuffer == null) continue; // Find logical group var cbufferNameSplit = cbuffer.Name.Text.IndexOf('.'); if (cbufferNameSplit == -1) continue; var cbufferName = cbuffer.Name.Text.Substring(0, cbufferNameSplit); var cbufferLogicalGroupName = cbufferNameSplit != -1 ? cbuffer.Name.Text.Substring(cbufferNameSplit + 1) : null; // Find or create a matching cbuffer var realCBuffer = constantBuffers.FirstOrDefault(x => x.Name.Text == cbufferName && x.Type == cbuffer.Type); if (realCBuffer == null) { // First time, let's create it realCBuffer = new ConstantBuffer { Name = cbufferName, Type = cbuffer.Type }; constantBuffers.Add(realCBuffer); } // Set cbuffer and logical groups variable.Key.SetTag(XenkoTags.ConstantBuffer, realCBuffer); variable.Key.SetTag(XenkoTags.LogicalGroup, cbufferLogicalGroupName); } var usefulVars = variables.Select(x => x.Key).Where(KeepVariableInCBuffer); var varList = usefulVars.Where(x => x.ContainsTag(XenkoTags.ConstantBuffer)).ToList(); var groupedVarList = varList.GroupBy(x => { var constantBuffer = x.GetTag(XenkoTags.ConstantBuffer) as ConstantBuffer; return (constantBuffer != null) ? constantBuffer.Name.Text : null; }).Select(x => x.ToList()).ToList(); foreach (var group in groupedVarList) { var originalCbuffer = (ConstantBuffer)group.First().GetTag(XenkoTags.ConstantBuffer); var cbuffer = new ConstantBuffer { Type = originalCbuffer.Type, Name = originalCbuffer.Name.Text }; cbuffer.Members.AddRange(group); MixedShader.Members.Add(cbuffer); } var remainingVars = usefulVars.Where(x => !x.ContainsTag(XenkoTags.ConstantBuffer)).ToList(); var globalBuffer = new ConstantBuffer { Type = SiliconStudio.Shaders.Ast.Hlsl.ConstantBufferType.Constant, Name = "Globals" }; if (remainingVars.Count > 0) { globalBuffer.Members.AddRange(remainingVars); MixedShader.Members.Add(globalBuffer); } // add textures, samplers etc. MixedShader.Members.AddRange(variables.Select(x => x.Key).Where(IsOutOfCBufferVariable)); }
public override void Visit(ConstantBuffer constantBuffer) { string remappedConstantBufferName; if (stringGenerics.TryGetValue(constantBuffer.Name.Text, out remappedConstantBufferName)) constantBuffer.Name = new Identifier(remappedConstantBufferName); base.Visit(constantBuffer); }