示例#1
0
            public static bool TryParse(string name, out Rmt2Descriptor descriptor)
            {
                descriptor = new Rmt2Descriptor();

                var parts = name.Split(new string[] { "shaders\\" }, StringSplitOptions.None);

                var prefixParts = parts[0].Split('\\');

                if (prefixParts.Length > 0 && prefixParts[0] == "ms30")
                {
                    descriptor.Flags |= DescriptorFlags.Ms30;
                }

                var nameParts = parts[1].Split('\\');

                if (nameParts.Length < 2)
                {
                    return(false);
                }

                descriptor.Type    = nameParts[0];
                descriptor.Options = nameParts[1].Split('_').Skip(1).Select(x => byte.Parse(x)).ToArray();

                return(true);
            }
示例#2
0
        private void FindClosestShaderTemplate(CachedTag sourceRmt2)
        {
            // somehow build a list of rmt2 of the same type
            List <CachedTag> candidateTemplates = new List <CachedTag>();

            // defined method search order, ignore last method from ms30
            List <int> methodOrder = new List <int> {
                0, 2, 3, 1, 6, 4, 5, 7, 8, 9, 10
            };

            Dictionary <CachedTag, int> matchLevelDictionary = new Dictionary <CachedTag, int>();
            Rmt2Descriptor sourceRmt2Desc;

            if (!Rmt2Descriptor.TryParse(sourceRmt2.Name, out sourceRmt2Desc))
            {
                return;
            }

            while (candidateTemplates.Count != 0)
            {
                var            template = candidateTemplates.Last();
                Rmt2Descriptor destRmt2Desc;
                if (!Rmt2Descriptor.TryParse(template.Name, out destRmt2Desc))
                {
                    candidateTemplates.Remove(template);
                    matchLevelDictionary[template] = 0;
                }
                else
                {
                    var matchLevel = 0;
                    for (int i = 0; i < methodOrder.Count; i++)
                    {
                        var methodIndex = methodOrder[i];
                        // we need to define a ordering on the method options, so that there is a single best rmt2
                        if (sourceRmt2Desc.Options[methodIndex] == destRmt2Desc.Options[methodIndex])
                        {
                            matchLevel++;
                        }
                        else
                        {
                            break;
                        }
                    }
                    matchLevelDictionary[template] = matchLevel;
                }
            }

            CachedTag bestRmt2  = null;
            var       bestScore = -1;
        }
示例#3
0
        /// <summary>
        /// Find the closest template in the base cache to the input template.
        /// </summary>
        private CachedTag FindClosestTemplate(CachedTag sourceRmt2Tag, RenderMethodTemplate sourceRmt2)
        {
            Debug.Assert(IsInitialized);

            Rmt2Descriptor sourceRmt2Desc;

            if (!Rmt2Descriptor.TryParse(sourceRmt2Tag.Name, out sourceRmt2Desc))
            {
                throw new ArgumentException($"Invalid rmt2 name '{sourceRmt2Tag.Name}'", nameof(sourceRmt2Tag));
            }

            var relevantRmt2s = new List <Rmt2Pairing>();

            foreach (var rmt2Tag in BaseCache.TagCache.NonNull().Where(tag => tag.IsInGroup("rmt2")))
            {
                Rmt2Descriptor destRmt2Desc;
                if (!Rmt2Descriptor.TryParse(rmt2Tag.Name, out destRmt2Desc))
                {
                    continue;
                }

                // ignore ms30 templates if desired
                if (!UseMs30 && destRmt2Desc.IsMs30)
                {
                    continue;
                }

                // ignore templates that are not of the same type
                if (destRmt2Desc.Type != sourceRmt2Desc.Type)
                {
                    continue;
                }

                // match the options from the rmt2 tag names
                int commonOptions = 0;
                for (int i = 0; i < sourceRmt2Desc.Options.Length; i++)
                {
                    if (sourceRmt2Desc.Options[i] == destRmt2Desc.Options[i])
                    {
                        commonOptions++;
                    }
                }

                // if we found an exact match, return it
                if (commonOptions == sourceRmt2Desc.Options.Length)
                {
                    return(rmt2Tag);
                }

                // add it to the list to be considered
                relevantRmt2s.Add(new Rmt2Pairing()
                {
                    CommonOptions = commonOptions,
                    DestTag       = rmt2Tag,
                    SourceTag     = sourceRmt2Tag
                });
            }

            // if we've reached here, we haven't found an extract match.
            // now we need to consider other factors such as which options they have, which parameters are missing etc..
            // whatever can be used to narrow it down.
            foreach (var pairing in relevantRmt2s)
            {
                var rmt2 = GetTemplate(pairing.DestTag);
                pairing.RealParams    = MatchParameterBlocks(sourceRmt2.RealParameterNames, rmt2.RealParameterNames);
                pairing.IntParams     = MatchParameterBlocks(sourceRmt2.IntegerParameterNames, rmt2.IntegerParameterNames);
                pairing.BoolParams    = MatchParameterBlocks(sourceRmt2.BooleanParameterNames, rmt2.BooleanParameterNames);
                pairing.TextureParams = MatchParameterBlocks(sourceRmt2.TextureParameterNames, rmt2.TextureParameterNames);
            }

            // finally order by some criteria
            var ordered = relevantRmt2s
                          .OrderBy(x => x.CommonOptions);
            //.ThenByDescending(x => x.MissingFromDest);


            // return the best rmt2 or the default if one could not be found (only when a template type is not in the base cache)
            var bestRmt2 = ordered.LastOrDefault()?.DestTag;

            if (bestRmt2 == null)
            {
                return(BaseCache.GetTag(DefaultTemplate));
            }

            return(bestRmt2);
        }