public override void VisitMethodDeclaration(MethodDeclarationSyntax node)
        {
            string functionName = node.Identifier.ToFullString();
            List <ParameterDefinition> parameters = new List <ParameterDefinition>();

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

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

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

            if (!isVertexShader)
            {
                isFragmentShader = Utilities.GetMethodAttributes(node, "FragmentShader").Any();
            }
            if (!isVertexShader && !isFragmentShader)
            {
                AttributeSyntax computeShaderAttr = Utilities.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 = Utilities.GetFullNestedTypePrefix(node, out bool nested);
            ShaderFunction sf = new ShaderFunction(
                nestedTypePrefix,
                functionName,
                returnType,
                parameters.ToArray(),
                type,
                computeGroupCounts);
            ShaderFunctionAndBlockSyntax sfab = new ShaderFunctionAndBlockSyntax(sf, node.Body);

            foreach (LanguageBackend b in _backends)
            {
                b.AddFunction(_shaderSet.Name, sfab);
            }
        }
Beispiel #2
0
 public ShaderFunction(
     string declaringType,
     string name,
     TypeReference returnType,
     ParameterDefinition[] parameters,
     ShaderFunctionType type,
     UInt3 computeGroupCounts)
 {
     DeclaringType      = declaringType;
     Name               = name;
     ReturnType         = returnType;
     Parameters         = parameters;
     Type               = type;
     ComputeGroupCounts = computeGroupCounts;
 }
Beispiel #3
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));
        }
Beispiel #4
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));
        }
Beispiel #5
0
 internal abstract string GetComputeGroupCountsDeclaration(UInt3 groupCounts);
 internal override string GetComputeGroupCountsDeclaration(UInt3 groupCounts)
 {
     return($"[numthreads({groupCounts.X}, {groupCounts.Y}, {groupCounts.Z})]");
 }
 internal override string GetComputeGroupCountsDeclaration(UInt3 groupCounts)
 {
     return($"layout(local_size_x = {groupCounts.X}, local_size_y = {groupCounts.Y}, local_size_z = {groupCounts.Z}) in;");
 }