Example #1
0
        private static bool CompileCode(LanguageBackend lang, string shaderPath, string entryPoint, ShaderFunctionType type, out string[] paths, bool debug)
        {
            Type langType = lang.GetType();

            if (langType == typeof(HlslBackend) && IsFxcAvailable())
            {
                bool result = CompileHlsl(shaderPath, entryPoint, type, out string path, debug);
                paths = new[] { path };
                return(result);
            }
            else if (langType == typeof(Glsl450Backend) && IsGlslangValidatorAvailable())
            {
                bool result = CompileSpirv(shaderPath, entryPoint, type, out string path);
                paths = new[] { path };
                return(result);
            }
            else if (langType == typeof(MetalBackend) && AreMetalMacOSToolsAvailable())
            {
                bool macOSresult = CompileMetal(shaderPath, true, out string pathMacOS);
                bool iosResult   = CompileMetal(shaderPath, false, out string pathiOS);
                paths = new[] { pathMacOS, pathiOS };
                return(macOSresult && iosResult);
            }
            else
            {
                paths = Array.Empty <string>();
                return(false);
            }
        }
Example #2
0
        protected void ValidateRequiredSemantics(string setName, ShaderFunction function, ShaderFunctionType type)
        {
            StructureDefinition outputType = null;

            if (function.ReturnType.TypeInfo.TypeKind == TypeKind.Struct &&
                function.ReturnType.TypeInfo.SpecialType != SpecialType.System_Void &&
                !ShaderPrimitiveTypes.IsPrimitiveType(function.ReturnType.TypeInfo.GetFullMetadataName()))
            {
                outputType = GetRequiredStructureType(setName, function.ReturnType);
            }
            foreach (ParameterDefinition pd in function.Parameters)
            {
                GetRequiredStructureType(setName, pd.Type);
            }
            if (type == ShaderFunctionType.FragmentEntryPoint)
            {
                if (outputType != null)
                {
                    foreach (FieldDefinition field in outputType.Fields)
                    {
                        if (field.SemanticType == SemanticType.None)
                        {
                            throw new ShaderGenerationException("Function return type is missing semantics on field: " + field.Name);
                        }
                    }
                }
            }
            else if (type == ShaderFunctionType.VertexEntryPoint)
            {
                foreach (ParameterDefinition pd in function.Parameters)
                {
                    StructureDefinition pType = GetRequiredStructureType(setName, pd.Type);
                    foreach (FieldDefinition field in pType.Fields)
                    {
                        if (field.SemanticType == SemanticType.None)
                        {
                            //throw new ShaderGenerationException(
                            //    $"Function parameter {pd.Name}'s type is missing semantics on field: {field.Name}");
                        }
                    }
                }
            }
        }
Example #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), semanticModel.GetTypeInfo(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));
        }
 protected void ValidateRequiredSemantics(string setName, ShaderFunction function, ShaderFunctionType type)
 {
     if (type == ShaderFunctionType.VertexEntryPoint)
     {
         StructureDefinition outputType = GetRequiredStructureType(setName, function.ReturnType);
         foreach (FieldDefinition field in outputType.Fields)
         {
             if (field.SemanticType == SemanticType.None)
             {
                 throw new ShaderGenerationException("Function return type is missing semantics on field: " + field.Name);
             }
         }
     }
     if (type != ShaderFunctionType.Normal)
     {
         foreach (ParameterDefinition pd in function.Parameters)
         {
             StructureDefinition pType = GetRequiredStructureType(setName, pd.Type);
             foreach (FieldDefinition field in pType.Fields)
             {
                 if (field.SemanticType == SemanticType.None)
                 {
                     throw new ShaderGenerationException(
                               $"Function parameter {pd.Name}'s type is missing semantics on field: {field.Name}");
                 }
             }
         }
     }
 }