Пример #1
0
        protected HashSet <ResourceDefinition> ProcessFunctions(string setName, ShaderFunctionAndMethodDeclarationSyntax entryPoint, out string funcs, out string entry)
        {
            HashSet <ResourceDefinition> resourcesUsed = new HashSet <ResourceDefinition>();
            StringBuilder sb = new StringBuilder();

            foreach (ShaderFunctionAndMethodDeclarationSyntax f in entryPoint.OrderedFunctionList)
            {
                if (!f.Function.IsEntryPoint)
                {
                    MethodProcessResult processResult = VisitShaderMethod(setName, f.Function).VisitFunction(f.MethodDeclaration);
                    foreach (ResourceDefinition rd in processResult.ResourcesUsed)
                    {
                        resourcesUsed.Add(rd);
                    }
                    sb.AppendLine(processResult.FullText);
                    foreach (var param in f.Function.Parameters)
                    {
                        resourcesUsed.Add(new ResourceDefinition(param.Name, 0, 0, param.Type, ShaderResourceKind.Local));
                    }
                }
            }
            funcs = sb.ToString();

            MethodProcessResult result = VisitShaderMethod(setName, entryPoint.Function).VisitFunction(entryPoint.MethodDeclaration);

            foreach (ResourceDefinition rd in result.ResourcesUsed)
            {
                resourcesUsed.Add(rd);
            }
            var context = GetContext(setName);

            foreach (var param in entryPoint.Function.Parameters)
            {
                var paramResource = new ResourceDefinition(param.Name, 0, 0, param.Type, ShaderResourceKind.Local);
                resourcesUsed.Add(paramResource);
                var sd = context.Structures.FirstOrDefault(paramResource.Matches);
                if (sd != null)
                {
                    int fieldIndex = 0;
                    foreach (var field in sd.Fields.Where(f => !f.IsBuiltIn))
                    {
                        resourcesUsed.Add(new ResourceDefinition(field.Name, 0, fieldIndex++, field.Type, ShaderResourceKind.Emit));
                    }
                }
            }

            entry = result.FullText;

            return(resourcesUsed);
        }
        internal override void AddResource(string setName, ResourceDefinition rd)
        {
            if (rd.ResourceKind == ShaderResourceKind.Uniform)
            {
                _uniformNames.Add(rd.Name);
            }
            if (rd.ResourceKind == ShaderResourceKind.StructuredBuffer ||
                rd.ResourceKind == ShaderResourceKind.RWStructuredBuffer)
            {
                _ssboNames.Add(rd.Name);
            }

            base.AddResource(setName, rd);
        }
Пример #3
0
        public override void VisitVariableDeclaration(VariableDeclarationSyntax node)
        {
            if (node.Variables.Count != 1)
            {
                throw new ShaderGenerationException("Cannot declare multiple variables together.");
            }

            VariableDeclaratorSyntax vds = node.Variables[0];

            string             resourceName = vds.Identifier.Text;
            TypeInfo           typeInfo     = GetModel(node).GetTypeInfo(node.Type);
            string             fullTypeName = GetModel(node).GetFullTypeName(node.Type);
            TypeReference      valueType    = new TypeReference(fullTypeName, typeInfo);
            ShaderResourceKind kind         = ClassifyResourceKind(fullTypeName);

            if (kind == ShaderResourceKind.StructuredBuffer ||
                kind == ShaderResourceKind.RWStructuredBuffer ||
                kind == ShaderResourceKind.RWTexture2D)
            {
                valueType = ParseElementType(vds);
            }

            int set = 0; // Default value if not otherwise specified.

            if (GetResourceDecl(node, out AttributeSyntax resourceSetDecl))
            {
                set = GetAttributeArgumentIntValue(resourceSetDecl, 0, GetModel(node));
            }

            int resourceBinding = GetAndIncrementBinding(set);

            ResourceDefinition rd = new ResourceDefinition(resourceName, set, resourceBinding, valueType, kind);

            if (kind == ShaderResourceKind.Uniform)
            {
                ValidateResourceType(typeInfo);
            }

            foreach (LanguageBackend b in _backends)
            {
                b.AddResource(_shaderSet.Name, rd);
            }
        }
Пример #4
0
        internal virtual void AddResource(string setName, ResourceDefinition rd)
        {
            if (rd == null)
            {
                throw new ArgumentNullException(nameof(rd));
            }

            if (rd.ResourceKind == ShaderResourceKind.Local)
            {
                GetContext(setName).Statics.Add(rd);
            }
            else
            {
                var context   = GetContext(setName);
                var structure = context.Structures.FirstOrDefault(s => s.Name == rd.ValueType.Name);
                if (structure == null || structure.Fields.All(f => !f.IsBuiltIn))
                {
                    context.Resources.Add(rd);
                }
            }
        }
Пример #5
0
 protected override void WriteTextureCube(StringBuilder sb, ResourceDefinition rd)
 {
     sb.AppendLine($"uniform samplerCube {CorrectIdentifier(rd.Name)};");
     sb.AppendLine();
 }
Пример #6
0
 protected override void WriteSampler(StringBuilder sb, ResourceDefinition rd)
 {
 }
Пример #7
0
 protected abstract void WriteTextureCube(StringBuilder sb, ResourceDefinition rd);
Пример #8
0
 protected abstract void WriteSampler(StringBuilder sb, ResourceDefinition rd);
Пример #9
0
 protected abstract void WriteUniform(StringBuilder sb, ResourceDefinition rd);
Пример #10
0
 private string FormatLayoutStr(ResourceDefinition rd)
 {
     return($"layout(binding = {rd.Binding})");
 }
Пример #11
0
 private void WriteRWStructuredBuffer(StringBuilder sb, ResourceDefinition rd, int binding)
 {
     sb.AppendLine($"RWStructuredBuffer<{CSharpToShaderType(rd.ValueType.Name)}> {CorrectIdentifier(rd.Name)}: register(u{binding});");
 }
Пример #12
0
 private void WriteTexture2DMS(StringBuilder sb, ResourceDefinition rd, int binding)
 {
     sb.AppendLine($"Texture2DMS<float4> {CorrectIdentifier(rd.Name)} : register(t{binding});");
     sb.AppendLine();
 }
Пример #13
0
 private void WriteSampler(StringBuilder sb, ResourceDefinition rd, int binding)
 {
     sb.AppendLine($"SamplerState {CorrectIdentifier(rd.Name)} : register(s{binding});");
     sb.AppendLine();
 }
Пример #14
0
        public override void VisitVariableDeclaration(VariableDeclarationSyntax node)
        {
            if (node.Variables.Count != 1)
            {
                throw new ShaderGenerationException("Cannot declare multiple variables together.");
            }

            VariableDeclaratorSyntax vds = node.Variables[0];

            string             resourceName = vds.Identifier.Text;
            TypeInfo           typeInfo     = GetModel(node).GetTypeInfo(node.Type);
            string             fullTypeName = GetModel(node).GetFullTypeName(node.Type);
            TypeReference      valueType    = new TypeReference(fullTypeName, typeInfo.Type);
            ShaderResourceKind kind         = ClassifyResourceKind(fullTypeName);

            var structure = _backends.Select(b => b.GetContext(_shaderSet.Name).Structures
                                             .FirstOrDefault(s => SymbolEqualityComparer.Default.Equals(s.Type, typeInfo.Type)))
                            .FirstOrDefault();

            if (structure != null && structure.Fields.Any(f => f.IsBuiltIn))
            {
                kind = ShaderResourceKind.BuiltIn;
            }

            ShaderBuiltin builtin = default;

            if (kind == ShaderResourceKind.Uniform)
            {
                if (node.Parent is FieldDeclarationSyntax field)
                {
                    if (field.Modifiers.Any(f => f.IsKind(SyntaxKind.PrivateKeyword)))
                    {
                        kind = ShaderResourceKind.Local;
                    }
                    else if (field.AttributeLists.Any(l => l.Attributes.Any(a => a.Name.ToString().Contains("Semantic"))))
                    {
                        kind = ShaderResourceKind.BuiltIn;
                        SemanticType semanticType = GetSemanticType(vds);
                        if (semanticType == SemanticType.None)
                        {
                            var geometrySemantic = GetGeometrySemantic(vds);
                            if (geometrySemantic != GeometrySemantic.None)
                            {
                                builtin = new ShaderBuiltin(geometrySemantic);
                            }
                        }
                        else
                        {
                            builtin = new ShaderBuiltin(semanticType);
                        }
                    }
                }
                else if (typeInfo.Type.GetAttributes().Any(a => a.AttributeClass.Name.Contains("Semantic")))
                {
                    kind = ShaderResourceKind.BuiltIn;
                }
            }

            if (kind == ShaderResourceKind.StructuredBuffer ||
                kind == ShaderResourceKind.RWStructuredBuffer ||
                kind == ShaderResourceKind.RWTexture2D ||
                valueType.Name.Contains(nameof(UniformBuffer <int>)))
            {
                valueType = ParseElementType(vds);
            }

            if (node.Parent is FieldDeclarationSyntax)
            {
                var arraySize = node.Parent.DescendantNodes().OfType <AttributeSyntax>().FirstOrDefault(
                    attrSyntax => attrSyntax.Name.ToString().EndsWith("ArraySize"));
                if (arraySize != null)
                {
                    var fixedSize = (int)GetModel(node).GetConstantValue(arraySize.ArgumentList.Arguments.First().Expression).Value;
                    valueType = new TypeReference(valueType.Name, valueType.TypeInfo, fixedSize);
                }

                var emitAttribute = node.Parent.DescendantNodes().OfType <AttributeSyntax>().FirstOrDefault(
                    attrSyntax => attrSyntax.Name.ToString().EndsWith("EmitVertex"));
                if (emitAttribute != null)
                {
                    kind = ShaderResourceKind.Emit;
                }
            }

            ResourceDefinition rd;

            if (kind == ShaderResourceKind.Local)
            {
                rd = new ResourceDefinition(resourceName, 0, 0, valueType, kind);
            }
            else
            {
                int set = 0; // Default value if not otherwise specified.
                if (GetResourceDecl(node, out AttributeSyntax resourceSetDecl))
                {
                    set = GetAttributeArgumentIntValue(resourceSetDecl, 0, GetModel(node));
                }

                int resourceBinding = GetAndIncrementBinding(set);

                if (kind == ShaderResourceKind.Uniform)
                {
                    ValidateUniformType(typeInfo);
                }
                rd = new ResourceDefinition(resourceName, set, resourceBinding, valueType, kind);
            }

            rd.Semantic = builtin.Semantic;

            foreach (LanguageBackend b in _backends)
            {
                b.AddResource(_shaderSet.Name, rd);
            }
        }
Пример #15
0
        private string FormatLayoutStr(ResourceDefinition rd, string storageSpec = null)
        {
            string storageSpecPart = storageSpec != null ? $"{storageSpec}, " : string.Empty;

            return($"layout({storageSpecPart}set = {rd.Set}, binding = {rd.Binding})");
        }
Пример #16
0
 protected abstract void WriteStructuredBuffer(StringBuilder sb, ResourceDefinition rd, bool isReadOnly);