예제 #1
0
        /// <summary>
        /// Loads additional static methods used by the shader
        /// </summary>
        /// <param name="name">The HLSL name of the new method to load</param>
        /// <param name="methodInfo">The <see cref="MethodInfo"/> instance for the method to load</param>
        private void LoadStaticMethodSource(string name, MethodInfo methodInfo)
        {
            // Decompile the target method
            MethodDecompiler.Instance.GetSyntaxTree(methodInfo, MethodType.Static, out MethodDeclarationSyntax root, out SemanticModel semanticModel);

            // Rewrite the method
            ShaderSyntaxRewriter syntaxRewriter = new ShaderSyntaxRewriter(semanticModel, methodInfo.DeclaringType);

            root = (MethodDeclarationSyntax)syntaxRewriter.Visit(root);

            // Register the captured static members
            foreach (var member in syntaxRewriter.StaticMembers)
            {
                LoadFieldInfo(member.Value, member.Key);
            }

            // Register the captured static methods
            foreach (var method in syntaxRewriter.StaticMethods)
            {
                LoadStaticMethodSource(method.Key, method.Value);
            }

            // Get the function parameters
            IReadOnlyList <ParameterInfo> parameters = (
                from parameter in root.ParameterList.Parameters.Select((p, i) => (Node: p, Index: i))
                let modifiers = parameter.Node.Modifiers
                                let type = parameter.Node.Type.ToFullString()
                                           let parameterName = parameter.Node.Identifier.ToFullString()
                                                               let last = parameter.Index == root.ParameterList.Parameters.Count - 1
                                                                          select new ParameterInfo(modifiers, type, parameterName, last)).ToArray();

            // Get the function body
            string body = root.Body.ToFullString();

            body = Regex.Replace(body, @"(?<=\W)(\d+)[fFdD]", m => m.Groups[1].Value);
            body = body.TrimEnd('\n', '\r', ' ');
            body = HlslKnownKeywords.GetMappedText(body);

            // Get the final function info instance
            FunctionInfo functionInfo = new FunctionInfo(
                methodInfo.ReturnType,
                $"{methodInfo.DeclaringType.FullName}{Type.Delimiter}{methodInfo.Name}",
                string.Join(", ", methodInfo.GetParameters().Select(p => $"{p.ParameterType.ToFriendlyString()} {p.Name}")),
                root.ReturnType.ToString(),
                name,
                parameters,
                body);

            _FunctionsList.Add(functionInfo);
        }
예제 #2
0
        /// <summary>
        /// Loads the entry method for the current shader being loaded
        /// </summary>
        private void LoadMethodSource()
        {
            // Decompile the shader method
            MethodDecompiler.Instance.GetSyntaxTree(Action.Method, MethodType.Closure, out MethodDeclarationSyntax root, out SemanticModel semanticModel);

            // Rewrite the shader method (eg. to fix the type declarations)
            ShaderSyntaxRewriter syntaxRewriter = new ShaderSyntaxRewriter(semanticModel, ShaderType);

            root = (MethodDeclarationSyntax)syntaxRewriter.Visit(root);

            // Extract the implicit local functions
            var locals = root.DescendantNodes().OfType <LocalFunctionStatementSyntax>().ToArray();

            root = root.RemoveNodes(locals, SyntaxRemoveOptions.KeepNoTrivia);
            foreach (var local in locals)
            {
                string alignedLocal = local.ToFullString().RemoveLeftPadding().Trim(' ', '\r', '\n');
                alignedLocal = Regex.Replace(alignedLocal, @"(?<=\W)(\d+)[fFdD]", m => m.Groups[1].Value);
                alignedLocal = HlslKnownKeywords.GetMappedText(alignedLocal);

                _LocalFunctionsList.Add(new LocalFunctionInfo(alignedLocal));
            }

            // Register the captured static members
            foreach (var member in syntaxRewriter.StaticMembers)
            {
                LoadFieldInfo(member.Value, member.Key);
            }

            // Register the captured static methods
            foreach (var method in syntaxRewriter.StaticMethods)
            {
                LoadStaticMethodSource(method.Key, method.Value);
            }

            // Get the thread ids identifier name and shader method body
            ThreadsIdsVariableName = root.ParameterList.Parameters.First().Identifier.Text;
            MethodBody             = root.Body.ToFullString();

            // Additional preprocessing
            MethodBody = Regex.Replace(MethodBody, @"(?<=\W)(\d+)[fFdD]", m => m.Groups[1].Value);
            MethodBody = MethodBody.TrimEnd('\n', '\r', ' ');
            MethodBody = HlslKnownKeywords.GetMappedText(MethodBody);
        }