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); } }
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}"); } } } } }
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}"); } } } } }