Ejemplo n.º 1
0
        /// <summary>
        /// Gets all the graphicsBackends, ensuring they have the required features.
        /// </summary>
        /// <param name="requiredFeatures">The required features.</param>
        /// <param name="throwOnFail">if set to <c>true</c> throws an error if any of the <paramref name="graphicsBackends" />
        /// do not have the <paramref name="requiredFeatures">required features</paramref>.</param>
        /// <param name="graphicsBackends">The graphics graphicsBackends.</param>
        /// <returns></returns>
        /// <exception cref="ShaderGen.Tests.Tools.RequiredToolFeatureMissingException"></exception>
        public static IReadOnlyList <ToolChain> Requires(
            ToolFeatures requiredFeatures,
            bool throwOnFail,
            IEnumerable <GraphicsBackend> graphicsBackends)
        {
            GraphicsBackend[] backends = (graphicsBackends ?? _toolChainsByGraphicsBackend.Keys).ToArray();
            if (backends.Length < 1)
            {
                backends = _toolChainsByGraphicsBackend.Keys.ToArray();
            }

            List <string>    missingBackends = new List <string>(backends.Length);
            List <ToolChain> found           = new List <ToolChain>(backends.Length);

            foreach (GraphicsBackend backend in backends)
            {
                ToolChain toolChain = Get(backend);
                if (toolChain == null)
                {
                    missingBackends.Add($"{backend} backend does not have a tool chain");
                    continue;
                }

                if (!toolChain.Features.HasFlag(requiredFeatures))
                {
                    missingBackends.Add(
                        $"{backend} tool chain does not have the required {~toolChain.Features & requiredFeatures} feature(s)");
                    continue;
                }

                found.Add(toolChain);
            }

            if (throwOnFail && missingBackends.Count > 0)
            {
                string last = missingBackends.LastOrDefault();
                throw new RequiredToolFeatureMissingException(
                          missingBackends.Count < 2
                        ? $"The {last}."
                        : $"The {string.Join(", ", missingBackends.Take(missingBackends.Count - 1))} and {last}.");
            }

            found.TrimExcess();
            return(found.AsReadOnly());
        }
Ejemplo n.º 2
0
 public static LanguageBackend[] GetAllBackends(Compilation compilation, ToolFeatures features = ToolFeatures.Transpilation)
 => ToolChain.Requires(features, false).Select(t => t.CreateBackend(compilation))
 .ToArray();
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ToolChain" /> class.  For now tool chains are single tools, but this
        /// could be easily extended to support multiple steps.
        /// </summary>
        /// <param name="graphicsBackend">The graphics backend.</param>
        /// <param name="backendType">Type of the backend.</param>
        /// <param name="createBackend">The function to create the backend.</param>
        /// <param name="compileFunction">The compile function.</param>
        /// <param name="createHeadless">The function to create a headless graphics device.</param>
        /// <param name="createWindowed">The create windowed.</param>
        /// <exception cref="ArgumentOutOfRangeException">backendType</exception>
        private ToolChain(GraphicsBackend graphicsBackend,
                          Type backendType,
                          Func <Compilation, LanguageBackend> createBackend,
                          CompileDelegate compileFunction,
                          Func <GraphicsDevice> createHeadless,
                          Func <GraphicsDevice> createWindowed)
        {
            if (!backendType.IsSubclassOf(typeof(LanguageBackend)))
            {
                throw new ArgumentOutOfRangeException(nameof(backendType),
                                                      $"{backendType.Name} is not a descendent of {nameof(LanguageBackend)}.");
            }

            BackendType = backendType;

            // Calculate name (strip 'Backend' if present).
            Name = backendType.Name;
            if (Name.EndsWith("Backend", StringComparison.InvariantCultureIgnoreCase))
            {
                Name = Name.Substring(0, Name.Length - 7);
            }

            GraphicsBackend = graphicsBackend;

            ToolFeatures features = ToolFeatures.None;

            if (createBackend != null)
            {
                _createBackend = createBackend;
                features      |= ToolFeatures.Transpilation;
            }

            if (compileFunction != null)
            {
                _compileFunction = compileFunction;

                features |= ToolFeatures.Compilation;
            }

            // Don't allow creation of graphics devices on CI Servers.
            bool onCiServer = Environment.GetEnvironmentVariable("CI")?.ToLowerInvariant() == "true";

            if (!onCiServer &&
                createHeadless != null &&
                GraphicsDevice.IsBackendSupported(graphicsBackend))
            {
                try
                {
                    // Try to create a headless graphics device
                    using (createHeadless()) { }
                    _createHeadless = createHeadless;
                    features       |= ToolFeatures.HeadlessGraphicsDevice;
                }
                catch
                {
                }
            }

            // TODO For future expansion, will need to review signature of function.
            if (!onCiServer &&
                createWindowed != null &&
                GraphicsDevice.IsBackendSupported(graphicsBackend))
            {
                try
                {
                    // Try to create a headless graphics device
                    using (createWindowed()) { }
                    _createWindowed = createWindowed;
                    features       |= ToolFeatures.WindowedGraphicsDevice;
                }
                catch
                {
                }
            }

            Features = features;

            // Add to lookup dictionaries.
            _toolChainsByGraphicsBackend.Add(graphicsBackend, this);
            _toolChainsByBackendType.Add(backendType, this);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Gets the first tool chain (if any) with all the specified features.
 /// </summary>
 /// <param name="features">The features.</param>
 /// <returns></returns>
 public static ToolChain Get(ToolFeatures features) =>
 Requires(features, false).FirstOrDefault();
Ejemplo n.º 5
0
 /// <summary>
 /// Gets all the graphicsBackends, ensuring they have the required features.
 /// </summary>
 /// <param name="requiredFeatures">The required features.</param>
 /// <param name="throwOnFail">if set to <c>true</c> throws an error if any of the <paramref name="graphicsBackends" />
 /// do not have the <paramref name="requiredFeatures">required features</paramref>.</param>
 /// <param name="graphicsBackends">The graphicsBackends required (leave empty to get all).</param>
 /// <returns></returns>
 /// <exception cref="ShaderGen.Tests.Tools.RequiredToolFeatureMissingException"></exception>
 public static IReadOnlyList <ToolChain> Requires(ToolFeatures requiredFeatures, bool throwOnFail,
                                                  params GraphicsBackend[] graphicsBackends)
 => Requires(requiredFeatures, throwOnFail, (IEnumerable <GraphicsBackend>)graphicsBackends);
Ejemplo n.º 6
0
 /// <summary>
 /// Gets all the graphicsBackends, ensuring they have the required features.
 /// </summary>
 /// <param name="requiredFeatures">The required features.</param>
 /// <param name="graphicsBackends">The graphicsBackends required (leave empty to get all).</param>
 /// <returns></returns>
 /// <exception cref="ShaderGen.Tests.Tools.RequiredToolFeatureMissingException"></exception>
 public static IReadOnlyList <ToolChain> Requires(ToolFeatures requiredFeatures, IEnumerable <GraphicsBackend> graphicsBackends)
 => Requires(requiredFeatures, true, graphicsBackends);
Ejemplo n.º 7
0
 /// <summary>
 /// Gets the graphicsBackends, ensuring it has the required features.
 /// </summary>
 /// <param name="requiredFeatures">The required features.</param>
 /// <param name="throwOnFail">if set to <c>true</c> throws an error if any of the <paramref name="graphicsBackends" />
 /// do not have the <paramref name="requiredFeatures">required features</paramref>.</param>
 /// <param name="graphicsBackend">The graphics backend.</param>
 /// <returns></returns>
 /// <exception cref="ShaderGen.Tests.Tools.RequiredToolFeatureMissingException"></exception>
 public static ToolChain Require(
     ToolFeatures requiredFeatures,
     bool throwOnFail,
     GraphicsBackend graphicsBackend) =>
 Requires(requiredFeatures, throwOnFail, graphicsBackend).SingleOrDefault();
Ejemplo n.º 8
0
 /// <summary>
 /// Gets the graphicsBackends, ensuring it has the required features.
 /// </summary>
 /// <param name="requiredFeatures">The required features.</param>
 /// <param name="graphicsBackend">The graphics backend.</param>
 /// <returns></returns>
 /// <exception cref="ShaderGen.Tests.Tools.RequiredToolFeatureMissingException"></exception>
 public static ToolChain Require(
     ToolFeatures requiredFeatures,
     GraphicsBackend graphicsBackend) =>
 Requires(requiredFeatures, true, graphicsBackend).SingleOrDefault();