コード例 #1
0
        private static void ParseModifier(ShaderLanguage foundation, XmlNode modifierNode)
        {
            XmlAttribute attName = modifierNode.Attributes["name"];

            if (attName == null)
            {
                return;
            }

            Modifier modifier = new Modifier();

            modifier.NativeText = attName.InnerText;
            foreach (XmlNode child in modifierNode)
            {
                if (child.Name.ToLower() != "requirement")
                {
                    continue;
                }

                XmlAttribute attCSharp = child.Attributes["csharp"];
                if (attCSharp != null && !string.IsNullOrWhiteSpace(attCSharp.InnerText))
                {
                    modifier.Requirements.Add(attCSharp.InnerText.ToLower());
                }
            }

            if (modifier.Requirements.Count > 0 && !string.IsNullOrWhiteSpace(modifier.NativeText))
            {
                foundation._modifiers.Add(modifier);
            }
        }
コード例 #2
0
 internal void Initialize(TranslationRunner runner, ShaderLanguage language, List <string> preprocessorSymbols, TranslationFlags flags)
 {
     Flags        = flags;
     Runner       = runner;
     Language     = language;
     ParseOptions = new CSharpParseOptions(LanguageVersion.CSharp7_3, DocumentationMode.Parse, SourceCodeKind.Regular, preprocessorSymbols);
 }
コード例 #3
0
        internal void Clear()
        {
            SourceSegment seg  = _lastSegment;
            SourceSegment prev = null;

            while (seg != null)
            {
                prev = seg.Previous;
                Pooling.SourceSegments.Put(seg);
                seg = prev;
            }

            _firstSegment = null;
            _lastSegment  = null;
            _curSegment   = null;

            foreach (ScopeInfo si in _scopes)
            {
                Pooling.Scopes.Put(si);
            }

            Pooling.Scopes.Put(_currentScope);

            _rootScope    = null;
            _currentScope = null;
            _language     = null;
        }
コード例 #4
0
        private static void ParseWord(ShaderLanguage foundation, XmlNode wordNode)
        {
            Type translatedType = ShaderType.RetrieveType(wordNode.Attributes["type"].InnerText);

            if (translatedType == null)
            {
                return;
            }

            bool uniformDimensionSingular = false;

            if (wordNode.Attributes["uniformSizeIsSingular"] != null)
            {
                bool.TryParse(wordNode.Attributes["uniformSizeIsSingular"].InnerText, out uniformDimensionSingular);
            }

            if (translatedType.IsGenericType)
            {
                foreach (XmlNode subTypeNode in wordNode)
                {
                    if (subTypeNode.Name.ToLower() != "generic")
                    {
                        continue;
                    }

                    string generic    = subTypeNode.Attributes["type"]?.InnerText;
                    string nativeName = subTypeNode.Attributes["name"]?.InnerText;

                    if (!string.IsNullOrWhiteSpace(generic) && !string.IsNullOrWhiteSpace(nativeName))
                    {
                        Type genericType = ShaderType.RetrieveType(generic) ?? throw new TypeAccessException($"The type {generic} is not valid in {foundation.Language} lexicon.");
                        Type finalType   = translatedType.MakeGenericType(genericType);

                        foundation._keywords.Add(finalType, new Translation()
                        {
                            NativeText            = nativeName,
                            UniformSizeIsSingular = uniformDimensionSingular,
                        });
                    }
                }
            }
            else
            {
                string generic    = wordNode.Attributes["type"]?.InnerText;
                string nativeName = wordNode.Attributes["name"]?.InnerText;

                if (!string.IsNullOrWhiteSpace(generic) && !string.IsNullOrWhiteSpace(nativeName))
                {
                    foundation._keywords.Add(translatedType, new Translation()
                    {
                        NativeText            = nativeName,
                        UniformSizeIsSingular = uniformDimensionSingular,
                    });
                }
            }
        }
コード例 #5
0
        /// <summary>
        /// Creates a new instance of <see cref="ShaderType"/>.
        /// </summary>
        /// <param name="translation">The language-specific translation of the original type.</param>
        /// <param name="originalType">The original type.</param>
        /// <param name="lang">The shader language which the type belongs to.</param>
        internal ShaderType(ShaderLanguage lang, string translation, Type originalType)
        {
            IsRegisteredType      = TypeHelper.IsRegisteredType(originalType);
            IsUnorderedAccessType = TypeHelper.IsUnorderedAccessType(originalType);

            _dimensions  = new List <int>();
            Dimensions   = _dimensions.AsReadOnly();
            Language     = lang;
            OriginalType = originalType;
            Translation  = translation;
            ElementType  = originalType.IsArray ? originalType.GetElementType() : originalType;
            WasArrayType = originalType.IsArray;

            if (ElementType.IsValueType)
            {
                if (typeof(IVector).IsAssignableFrom(ElementType))
                {
                    IsVector = true;
                    int elementCount = (int)ElementType.GetField("ELEMENT_COUNT").GetValue(null);
                    SubElementSizeOf = (int)ElementType.GetField("ELEMENT_SIZE").GetValue(null);
                    SizeOf           = (int)ElementType.GetField("SIZE_OF").GetValue(null);
                    Type eType = (Type)ElementType.GetField("ElementType").GetValue(null);

                    _dataTypes.TryGetValue(eType, out _dataType);
                    _dimensions.Add(elementCount);
                }
                else if (typeof(IMatrix).IsAssignableFrom(ElementType))
                {
                    IsMatrix = true;
                    int rowCount = (int)ElementType.GetField("ROW_COUNT").GetValue(null);
                    int colCount = (int)ElementType.GetField("COLUMN_COUNT").GetValue(null);
                    SubElementSizeOf = (int)ElementType.GetField("ELEMENT_SIZE").GetValue(null);
                    SizeOf           = (int)ElementType.GetField("SIZE_OF").GetValue(null);
                    Type eType = (Type)ElementType.GetField("ElementType").GetValue(null);

                    _dataTypes.TryGetValue(eType, out _dataType);
                    _dimensions.Add(rowCount);
                    _dimensions.Add(colCount);
                }
                else
                {
                    SubElementSizeOf = Marshal.SizeOf(ElementType);
                    SizeOf           = SubElementSizeOf;
                    _dataTypes.TryGetValue(ElementType, out _dataType);
                    _dimensions.Add(1);
                }
            }

            SubElementCount = GetTotalElements();
        }
コード例 #6
0
 internal void Initialize(ShaderTranslationContext sc, TranslationFlags flags)
 {
     _flags                  = flags;
     _language               = sc.Language;
     _currentScope           = Pooling.Scopes.Get();
     _currentScope.Type      = ScopeType.Class;
     _currentScope.TypeInfo  = new ShaderType(_language, sc.ShaderType.Name, sc.ShaderType);
     _currentScope.Namespace = $"{sc.ShaderType.Namespace}.{sc.ShaderType.Name}";
     _rootScope              = _currentScope;
     _firstSegment           = Pooling.SourceSegments.Get();
     _firstSegment.Value     = "";
     _curSegment             = _firstSegment;
     _lastSegment            = _curSegment;
 }
コード例 #7
0
        internal TranslationRunner()
        {
            _processors = new Dictionary <Type, NodeProcessor>();

            ShaderLanguage.LoadEmbedded <HlslLanguage>("SharpShader.Languages.HLSL.lang.xml");
            ShaderLanguage.LoadEmbedded <GlslFoundation>("SharpShader.Languages.GLSL.lang.xml");

            // Preprocessors
            IEnumerable <Type> types = ShaderType.FindOfType <NodeProcessor>();

            foreach (Type t in types)
            {
                NodeProcessor pp = Activator.CreateInstance(t) as NodeProcessor;
                _processors.Add(pp.ParsedType, pp);
            }
        }
コード例 #8
0
        internal static void LoadEmbedded <T>(string embeddedName) where T : ShaderLanguage
        {
            using (Stream stream = EmbeddedResource.GetStream(embeddedName))
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(stream);

                foreach (XmlNode rootNode in doc)
                {
                    if (rootNode.Name.ToLower() != "lexicon")
                    {
                        continue;
                    }

                    XmlAttribute attLanguage = rootNode.Attributes["language"];
                    if (attLanguage != null && Enum.TryParse(attLanguage.InnerText, out OutputLanguage language))
                    {
                        ShaderLanguage foundation = Activator.CreateInstance(typeof(T),
                                                                             BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                                                                             null, new object[] { language }, null) as ShaderLanguage;

                        foreach (XmlNode node in rootNode)
                        {
                            switch (node.Name.ToLower())
                            {
                            case "word":
                                ParseWord(foundation, node);
                                break;

                            case "modifier":
                                ParseModifier(foundation, node);
                                break;
                            }
                        }

                        _foundations.Add(language, foundation);
                    }
                    else
                    {
                        throw new XmlException("The specified shader language is invalid or missing.");
                    }
                }
            }
        }
コード例 #9
0
        internal TranslationContext Run(TranslationArgs args)
        {
            List <string> preprocessorSymbols = null;

            if (args.PreprocessorSymbols != null)
            {
                preprocessorSymbols = new List <string>(args.PreprocessorSymbols);
            }

            Stopwatch mainTimer = new Stopwatch();

            mainTimer.Start();

            ShaderLanguage     foundation = ShaderLanguage.Get(args.Language);
            TranslationContext context    = Pooling.Contexts.Get();

            context.Initialize(this, foundation, preprocessorSymbols, args.Flags);

            Message("Analyzing", TranslationMessageType.Status);
            AnalysisInfo analysis = Analyze(context, args.CSharpSources);

            Message($"Analysis completed");

            if (analysis.HasError)
            {
                foreach (TranslationMessage msg in context.Messages)
                {
                    Message(msg.Text, msg.MessageType);
                }

                Message($"Cannot proceed until errors are fixed. Aborting.");
            }
            else
            {
                Message($"Mapping shader classes", TranslationMessageType.Status);
                Map(context, analysis.Trees);
                Message($"Mapping completed. Found {context.Shaders.Count} shader classes.");

                foreach (ShaderTranslationContext sc in context.Shaders)
                {
                    Message($"Translating {sc.Name}", TranslationMessageType.Status);
                    Stopwatch timer = new Stopwatch();
                    timer.Start();

                    Message($"Translating to {context.Language.Language}");
                    Translate(sc, sc.RootNode);
                    sc.FinalSource = sc.Source.ToString();

                    timer.Stop();
                    Message($"  Finished '{sc.Name}' in {timer.Elapsed.TotalMilliseconds:N2} milliseconds");
                }

                mainTimer.Stop();
                foreach (TranslationMessage msg in context.Messages)
                {
                    Message(msg.Text, msg.MessageType);
                }

                int errors   = context.Messages.Count(t => t.MessageType == TranslationMessageType.Error);
                int warnings = context.Messages.Count(t => t.MessageType == TranslationMessageType.Warning);
                Message($"Finished conversion of { args.CSharpSources.Count} source(s) with {errors} errors and {warnings} warnings. ");
                Message($"Took {mainTimer.Elapsed.TotalMilliseconds:N2} milliseconds");
            }

            return(context);
        }