Ejemplo n.º 1
0
        protected override string GetFunctionDeclStr()
        {
            string returnType   = _backend.CSharpToShaderType(_shaderFunction.ReturnType.Name);
            string fullDeclType = _backend.CSharpToShaderType(_shaderFunction.DeclaringType);
            string funcName     = _shaderFunction.IsEntryPoint
                ? _shaderFunction.Name
                : fullDeclType + "_" + _shaderFunction.Name;
            string baseParameterList    = GetParameterDeclList();
            string builtinParameterList = string.Join(
                ", ",
                MetalBackend.GetBuiltinParameterList(_shaderFunction).Select(b => $"{b.Type} {b.Name}"));
            string fullParameterList = string.Join(
                ", ",
                new string[]
            {
                baseParameterList, builtinParameterList
            }.Where(s => !string.IsNullOrEmpty(s)));

            string functionDeclStr = $"{returnType} {funcName}({fullParameterList})";

            return(functionDeclStr);
        }
Ejemplo n.º 2
0
        protected override MethodProcessResult GenerateFullTextCore(string setName, ShaderFunction function)
        {
            Debug.Assert(function.IsEntryPoint);

            StringBuilder  sb         = new StringBuilder();
            BackendContext setContext = GetContext(setName);
            ShaderFunctionAndMethodDeclarationSyntax entryPoint = setContext.Functions.SingleOrDefault(
                sfabs => sfabs.Function.Name == function.Name);

            if (entryPoint == null)
            {
                throw new ShaderGenerationException("Couldn't find given function: " + function.Name);
            }

            ValidateRequiredSemantics(setName, entryPoint.Function, function.Type);

            // Write header
            sb.AppendLine("#include <metal_stdlib>");
            sb.AppendLine("using namespace metal;");

            // TODO: Necessary for Metal?
            StructureDefinition[] orderedStructures
                = StructureDependencyGraph.GetOrderedStructureList(Compilation, setContext.Structures);
            foreach (StructureDefinition sd in orderedStructures)
            {
                WriteStructure(sb, sd);
            }

            HashSet <ResourceDefinition> resourcesUsed
                = ProcessFunctions(setName, entryPoint, out string funcsStr, out string entryStr);

            ValidateResourcesUsed(setName, resourcesUsed);

            StringBuilder containerSB = new StringBuilder();

            containerSB.AppendLine("struct ShaderContainer {");

            List <string> structFields    = new List <string>();
            List <string> ctorParams      = new List <string>();
            List <string> ctorAssignments = new List <string>();

            foreach (ResourceDefinition resource in resourcesUsed)
            {
                structFields.Add(GetResourceField(resource));
                ctorParams.Add(GetResourceCtorParam(resource));
                ctorAssignments.Add($"{resource.Name}({resource.Name}_param)");
            }

            foreach (string sf in structFields)
            {
                containerSB.AppendLine(sf);
            }

            containerSB.AppendLine(funcsStr);

            // Emit the ctor definition
            containerSB.AppendLine($"ShaderContainer(");
            string ctorParamsStr = string.Join(", ", ctorParams);

            containerSB.AppendLine(ctorParamsStr);
            containerSB.AppendLine($")");
            string allCtorAssignments = string.Join(", ", ctorAssignments);

            if (!string.IsNullOrEmpty(allCtorAssignments))
            {
                containerSB.AppendLine(":");
                containerSB.AppendLine(allCtorAssignments);
            }
            containerSB.AppendLine("{}");

            containerSB.AppendLine(entryStr);

            containerSB.AppendLine("};"); // Close the global containing struct.
            sb.AppendLine(containerSB.ToString());

            // Emit the out function call which creates the container struct and calls the real shader function.
            string type = entryPoint.Function.Type == ShaderFunctionType.VertexEntryPoint
                ? "vertex"
                : entryPoint.Function.Type == ShaderFunctionType.FragmentEntryPoint
                    ? "fragment"
                    : "kernel";

            ShaderFunction entryFunction         = entryPoint.Function;
            string         returnType            = CSharpToShaderType(entryFunction.ReturnType.Name);
            string         fullDeclType          = CSharpToShaderType(entryFunction.DeclaringType);
            string         funcName              = entryFunction.Name;
            string         baseParameterList     = string.Join(", ", entryFunction.Parameters.Select(FormatParameter));
            string         resourceParameterList = GetResourceParameterList(entryFunction, setName, resourcesUsed);
            string         builtinParameterList  = string.Join(
                ", ",
                GetBuiltinParameterList(entryFunction).Select(b => $"{b.Type} {b.Name} {b.Attribute}"));
            string fullParameterList = string.Join(
                ", ",
                new string[]
            {
                baseParameterList, resourceParameterList, builtinParameterList
            }.Where(s => !string.IsNullOrEmpty(s)));

            string functionDeclStr = $"{type} {returnType} {funcName}({fullParameterList})";

            string containerArgs = string.Join(", ", resourcesUsed.Select(
                                                   rd => rd.Name));

            string entryFuncArgs = string.Join(
                ", ",
                MetalBackend.GetBuiltinParameterList(entryFunction).Select(b => $"{b.Name}"));

            if (entryFunction.Parameters.Length > 0)
            {
                Debug.Assert(entryFunction.Parameters.Length == 1);
                entryFuncArgs = Utilities.JoinIgnoreNull(
                    ", ",
                    new string[] { $"{entryFunction.Parameters[0].Name}", entryFuncArgs });
            }

            sb.AppendLine(functionDeclStr);
            sb.AppendLine("{");
            sb.AppendLine($"return ShaderContainer({containerArgs}).{entryFunction.Name}({entryFuncArgs});");
            sb.AppendLine("}");

            return(new MethodProcessResult(sb.ToString(), resourcesUsed));
        }