Exemplo n.º 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);
                }
            }
            funcs = sb.ToString();

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

            foreach (ResourceDefinition rd in result.ResourcesUsed)
            {
                resourcesUsed.Add(rd);
            }

            entry = result.FullText;

            return(resourcesUsed);
        }
Exemplo n.º 2
0
        internal string FormatInvocation(string setName, string type, string method, InvocationParameterInfo[] parameterInfos)
        {
            Debug.Assert(setName != null);
            Debug.Assert(type != null);
            Debug.Assert(method != null);
            Debug.Assert(parameterInfos != null);

            ShaderFunctionAndMethodDeclarationSyntax function = GetContext(setName).Functions
                                                                .SingleOrDefault(
                sfabs => sfabs.Function.DeclaringType == type && sfabs.Function.Name == method &&
                parameterInfos.Length == sfabs.Function.Parameters.Length);

            if (function != null)
            {
                ParameterDefinition[] funcParameters = function.Function.Parameters;
                string[] formattedParams             = new string[funcParameters.Length];
                for (int i = 0; i < formattedParams.Length; i++)
                {
                    formattedParams[i] = FormatInvocationParameter(funcParameters[i], parameterInfos[i]);
                }

                string invocationList = string.Join(", ", formattedParams);
                string fullMethodName = CSharpToShaderType(function.Function.DeclaringType) + "_" + function.Function.Name;
                return($"{fullMethodName}({invocationList})");
            }
            else
            {
                return(FormatInvocationCore(setName, type, method, parameterInfos));
            }
        }
Exemplo n.º 3
0
        public override void VisitMethodDeclaration(MethodDeclarationSyntax node)
        {
            ShaderFunctionAndMethodDeclarationSyntax sfab = Utilities.GetShaderFunction(node, _compilation, true);

            foreach (LanguageBackend b in _backends)
            {
                b.AddFunction(_shaderSet.Name, sfab);

                foreach (var calledFunction in sfab.OrderedFunctionList)
                {
                    b.AddFunction(_shaderSet.Name, calledFunction);
                }
            }
        }
Exemplo n.º 4
0
        internal virtual void AddFunction(string setName, ShaderFunctionAndMethodDeclarationSyntax sf)
        {
            if (sf == null)
            {
                throw new ArgumentNullException(nameof(sf));
            }

            var context = GetContext(setName);

            if (!context.Functions.Contains(sf))
            {
                context.Functions.Add(sf);
            }
        }
Exemplo n.º 5
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);
        }
Exemplo n.º 6
0
        private void TraverseNode(HashSet <ShaderFunctionAndMethodDeclarationSyntax> result, CallGraphNode node)
        {
            foreach (ShaderFunctionAndMethodDeclarationSyntax existing in result)
            {
                if (node.Parents.Any(cgn => cgn.Name.Equals(existing)))
                {
                    throw new ShaderGenerationException("There was a cyclical call graph involving " + existing + " and " + node.Name);
                }
            }

            foreach (CallGraphNode child in node.Children)
            {
                TraverseNode(result, child);
            }

            ShaderFunctionAndMethodDeclarationSyntax sfab = Utilities.GetShaderFunction(node.Declaration, Compilation, false);

            result.Add(sfab);
        }
Exemplo n.º 7
0
        internal static ShaderFunctionAndMethodDeclarationSyntax GetShaderFunction(
            MethodDeclarationSyntax node,
            Compilation compilation,
            bool generateOrderedFunctionList)
        {
            string functionName = node.Identifier.ToFullString();
            List <ParameterDefinition> parameters = new List <ParameterDefinition>();

            foreach (ParameterSyntax ps in node.ParameterList.Parameters)
            {
                parameters.Add(ParameterDefinition.GetParameterDefinition(compilation, ps));
            }

            SemanticModel semanticModel = compilation.GetSemanticModel(node.SyntaxTree);

            TypeReference returnType = new TypeReference(semanticModel.GetFullTypeName(node.ReturnType));

            UInt3 computeGroupCounts = new UInt3();
            bool  isFragmentShader = false, isComputeShader = false;
            bool  isVertexShader = GetMethodAttributes(node, "VertexShader").Any();

            if (!isVertexShader)
            {
                isFragmentShader = GetMethodAttributes(node, "FragmentShader").Any();
            }
            if (!isVertexShader && !isFragmentShader)
            {
                AttributeSyntax computeShaderAttr = GetMethodAttributes(node, "ComputeShader").FirstOrDefault();
                if (computeShaderAttr != null)
                {
                    isComputeShader      = true;
                    computeGroupCounts.X = GetAttributeArgumentUIntValue(computeShaderAttr, 0);
                    computeGroupCounts.Y = GetAttributeArgumentUIntValue(computeShaderAttr, 1);
                    computeGroupCounts.Z = GetAttributeArgumentUIntValue(computeShaderAttr, 2);
                }
            }

            ShaderFunctionType type = isVertexShader
                ? ShaderFunctionType.VertexEntryPoint
                : isFragmentShader
                    ? ShaderFunctionType.FragmentEntryPoint
                    : isComputeShader
                        ? ShaderFunctionType.ComputeEntryPoint
                        : ShaderFunctionType.Normal;

            string         nestedTypePrefix = GetFullNestedTypePrefix(node, out bool nested);
            ShaderFunction sf = new ShaderFunction(
                nestedTypePrefix,
                functionName,
                returnType,
                parameters.ToArray(),
                type,
                computeGroupCounts);

            ShaderFunctionAndMethodDeclarationSyntax[] orderedFunctionList;
            if (type != ShaderFunctionType.Normal && generateOrderedFunctionList)
            {
                FunctionCallGraphDiscoverer fcgd = new FunctionCallGraphDiscoverer(
                    compilation,
                    new TypeAndMethodName {
                    TypeName = sf.DeclaringType, MethodName = sf.Name
                });
                fcgd.GenerateFullGraph();
                orderedFunctionList = fcgd.GetOrderedCallList();
            }
            else
            {
                orderedFunctionList = new ShaderFunctionAndMethodDeclarationSyntax[0];
            }

            return(new ShaderFunctionAndMethodDeclarationSyntax(sf, node, orderedFunctionList));
        }
Exemplo n.º 8
0
        internal static ShaderFunctionAndMethodDeclarationSyntax GetShaderFunction(
            BaseMethodDeclarationSyntax node,
            Compilation compilation,
            bool generateOrderedFunctionList)
        {
            SemanticModel semanticModel = compilation.GetSemanticModel(node.SyntaxTree);

            string        functionName;
            TypeReference returnTypeReference;

            if (node is MethodDeclarationSyntax mds)
            {
                functionName        = mds.Identifier.ToFullString();
                returnTypeReference = new TypeReference(semanticModel.GetFullTypeName(mds.ReturnType), semanticModel.GetTypeInfo(mds.ReturnType).Type);
            }
            else if (node is ConstructorDeclarationSyntax cds)
            {
                functionName = ".ctor";
                ITypeSymbol typeSymbol = semanticModel.GetDeclaredSymbol(cds).ContainingType;
                returnTypeReference = new TypeReference(GetFullTypeName(typeSymbol, out _), typeSymbol);
            }
            else
            {
                throw new ArgumentOutOfRangeException(nameof(node), "Unsupported BaseMethodDeclarationSyntax type.");
            }

            UInt3 computeGroupCounts = new UInt3();
            bool  isFragmentShader = false, isComputeShader = false;
            bool  isVertexShader   = GetMethodAttributes(node, "VertexShader").Any();
            bool  isGeometryShader = GetMethodAttributes(node, "GeometryShader").Any();

            if (!isVertexShader)
            {
                isFragmentShader = GetMethodAttributes(node, "FragmentShader").Any();
            }
            if (!isVertexShader && !isFragmentShader && !isGeometryShader)
            {
                AttributeSyntax computeShaderAttr = GetMethodAttributes(node, "ComputeShader").FirstOrDefault();
                if (computeShaderAttr != null)
                {
                    isComputeShader      = true;
                    computeGroupCounts.X = GetAttributeArgumentUIntValue(computeShaderAttr, 0);
                    computeGroupCounts.Y = GetAttributeArgumentUIntValue(computeShaderAttr, 1);
                    computeGroupCounts.Z = GetAttributeArgumentUIntValue(computeShaderAttr, 2);
                }
            }

            ShaderFunctionType type = isVertexShader
                ? ShaderFunctionType.VertexEntryPoint
                : isFragmentShader
                    ? ShaderFunctionType.FragmentEntryPoint
                    : isComputeShader
                        ? ShaderFunctionType.ComputeEntryPoint
                        : isGeometryShader
                            ? ShaderFunctionType.GeometryEntryPoint
                            : ShaderFunctionType.Normal;

            string nestedTypePrefix = GetFullNestedTypePrefix(node, out bool nested);

            List <ParameterDefinition> parameters = new List <ParameterDefinition>();

            foreach (ParameterSyntax ps in node.ParameterList.Parameters)
            {
                parameters.Add(ParameterDefinition.GetParameterDefinition(compilation, ps));
            }

            ShaderFunction sf = new ShaderFunction(
                nestedTypePrefix,
                functionName,
                returnTypeReference,
                parameters.ToArray(),
                type,
                computeGroupCounts);

            if (isGeometryShader)
            {
                AttributeSyntax geometryShaderAttr = GetMethodAttributes(node, "GeometryShader").FirstOrDefault();
                var             geometryArgs       = geometryShaderAttr.ArgumentList.Arguments;
                if (geometryArgs.Count == 3)
                {
                    sf.InputPrimitive  = (PrimitiveType)Enum.ToObject(typeof(PrimitiveType), semanticModel.GetConstantValue(geometryArgs[0].Expression).Value);
                    sf.OutputPrimitive = (PrimitiveType)Enum.ToObject(typeof(PrimitiveType), semanticModel.GetConstantValue(geometryArgs[1].Expression).Value);
                    sf.MaxVertices     = (int)semanticModel.GetConstantValue(geometryArgs[2].Expression).Value;
                }
            }

            ShaderFunctionAndMethodDeclarationSyntax[] orderedFunctionList;
            if (type != ShaderFunctionType.Normal && generateOrderedFunctionList)
            {
                FunctionCallGraphDiscoverer fcgd = new FunctionCallGraphDiscoverer(
                    compilation,
                    new TypeAndMethodName {
                    TypeName = sf.DeclaringType, MethodName = sf.Name
                });
                fcgd.GenerateFullGraph();
                orderedFunctionList = fcgd.GetOrderedCallList();
            }
            else
            {
                orderedFunctionList = new ShaderFunctionAndMethodDeclarationSyntax[0];
            }

            return(new ShaderFunctionAndMethodDeclarationSyntax(sf, node, orderedFunctionList));
        }