Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        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();
                }
            }
        }
Ejemplo n.º 3
0
 protected void Visit(ConstantBuffer constantBuffer)
 {
     foreach (var variable in constantBuffer.Members.OfType<Variable>().SelectMany(x => x.Instances()))
     {
         ParseConstantBufferVariable(constantBuffer.Name, variable);
     }
 }
Ejemplo n.º 4
0
 public void Visit(ConstantBuffer constantBuffer)
 {
     currentConstantBuffer = constantBuffer;
     Visit((Node)constantBuffer);
     currentConstantBuffer = null;
 }
Ejemplo n.º 5
0
        // 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));
        }
Ejemplo n.º 6
0
 public override void Visit(ConstantBuffer constantBuffer)
 {
     currentConstantBuffer = constantBuffer;
     base.Visit(constantBuffer);
     currentConstantBuffer = null;
 }
Ejemplo n.º 7
0
        /// <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(); 
        }
Ejemplo n.º 8
0
        /// <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();
                }
            }
        }
Ejemplo n.º 9
0
        // 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);
        }