Пример #1
0
        private Effect CreateEffect(string effectName, EffectBytecode bytecode, ShaderMixinParameters usedParameters)
        {
            Effect effect;

            lock (cachedEffects)
            {
                if (!cachedEffects.TryGetValue(bytecode, out effect))
                {
                    effect = new Effect(graphicsDeviceService.GraphicsDevice, bytecode, usedParameters)
                    {
                        Name = effectName
                    };
                    cachedEffects.Add(bytecode, effect);

#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
                    foreach (var type in bytecode.HashSources.Keys)
                    {
                        // TODO: the "/path" is hardcoded, used in ImportStreamCommand and ShaderSourceManager. Find a place to share this correctly.
                        using (var pathStream = Asset.OpenAsStream(EffectCompilerBase.GetStoragePathFromShaderType(type) + "/path"))
                            using (var reader = new StreamReader(pathStream))
                            {
                                var path = reader.ReadToEnd();
                                directoryWatcher.Track(path);
                            }
                    }
#endif
                }
            }
            return(effect);
        }
Пример #2
0
 public string GetPathOfXkslShader(string effectName)
 {
     using (var pathStream = FileProvider.OpenStream(EffectCompilerBase.GetStoragePathFromShaderType(effectName) + "/path", VirtualFileMode.Open, VirtualFileAccess.Read))
         using (var reader = new StreamReader(pathStream))
         {
             return(reader.ReadToEnd());
         }
 }
Пример #3
0
        private CompilerResults GetCompilerResults(string effectName, CompilerParameters compilerParameters, out string subEffect)
        {
            compilerParameters.Profile = GraphicsDevice.ShaderProfile.HasValue ? GraphicsDevice.ShaderProfile.Value : graphicsDeviceService.GraphicsDevice.Features.Profile;
#if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLCORE
            compilerParameters.Platform = GraphicsPlatform.OpenGL;
#endif
#if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES
            compilerParameters.Platform = GraphicsPlatform.OpenGLES;
#endif

            // Get main effect name (before the first dot)
            var mainEffectName = EffectCompilerBase.GetEffectName(effectName, out subEffect);

            // Compile shader
            var isPdxfx = ShaderMixinManager.Contains(mainEffectName);
            var source  = isPdxfx ? new ShaderMixinGeneratorSource(effectName) : (ShaderSource) new ShaderClassSource(mainEffectName);

            // getting the effect from the used parameters only makes sense when the source files are the same
            // TODO: improve this by updating earlyCompilerCache - cache can still be relevant

            CompilerResults compilerResult = null;

            if (isPdxfx)
            {
                // perform an early test only based on the parameters
                compilerResult = GetShaderFromParameters(mainEffectName, subEffect, compilerParameters);
            }

            if (compilerResult == null)
            {
                compilerResult = compiler.Compile(source, compilerParameters);

                if (!compilerResult.HasErrors && isPdxfx)
                {
                    lock (earlyCompilerCache)
                    {
                        List <CompilerResults> effectCompilerResults;
                        if (!earlyCompilerCache.TryGetValue(mainEffectName, out effectCompilerResults))
                        {
                            effectCompilerResults = new List <CompilerResults>();
                            earlyCompilerCache.Add(mainEffectName, effectCompilerResults);
                        }

                        // Register bytecode used parameters so that they are checked when another effect is instanced
                        effectCompilerResults.Add(compilerResult);
                    }
                }
            }

            foreach (var message in compilerResult.Messages)
            {
                Log.Log(message);
            }

            return(compilerResult);
        }
Пример #4
0
        private Effect CreateEffect(string effectName, EffectBytecodeCompilerResult effectBytecodeCompilerResult, CompilerResults compilerResult)
        {
            Effect effect;

            lock (cachedEffects)
            {
                if (!isInitialized)
                {
                    throw new InvalidOperationException("EffectSystem has been disposed. This Effect compilation has been cancelled.");
                }

                var usedParameters = compilerResult.UsedParameters;

                if (effectBytecodeCompilerResult.CompilationLog.HasErrors)
                {
                    // Unregister result (or should we keep it so that failure never change?)
                    List <CompilerResults> effectCompilerResults;
                    if (earlyCompilerCache.TryGetValue(effectName, out effectCompilerResults))
                    {
                        effectCompilerResults.Remove(compilerResult);
                    }
                }

                CheckResult(effectBytecodeCompilerResult.CompilationLog);

                var bytecode = effectBytecodeCompilerResult.Bytecode;
                if (bytecode == null)
                {
                    throw new InvalidOperationException("EffectCompiler returned no shader and no compilation error.");
                }

                if (!cachedEffects.TryGetValue(bytecode, out effect))
                {
                    effect = new Effect(graphicsDeviceService.GraphicsDevice, bytecode, usedParameters)
                    {
                        Name = effectName
                    };
                    cachedEffects.Add(bytecode, effect);

#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
                    foreach (var type in bytecode.HashSources.Keys)
                    {
                        // TODO: the "/path" is hardcoded, used in ImportStreamCommand and ShaderSourceManager. Find a place to share this correctly.
                        using (var pathStream = FileProvider.OpenStream(EffectCompilerBase.GetStoragePathFromShaderType(type) + "/path", VirtualFileMode.Open, VirtualFileAccess.Read))
                            using (var reader = new StreamReader(pathStream))
                            {
                                var path = reader.ReadToEnd();
                                directoryWatcher.Track(path);
                            }
                    }
#endif
                }
            }
            return(effect);
        }
Пример #5
0
        public CompilerResults GetCompilerResults(string effectName, CompilerParameters compilerParameters)
        {
            if (effectName == null)
            {
                throw new ArgumentNullException("effectName");
            }
            if (compilerParameters == null)
            {
                throw new ArgumentNullException("compilerParameters");
            }

            // Setup compilation parameters
            compilerParameters.EffectParameters.Platform = GraphicsDevice.Platform;
            compilerParameters.EffectParameters.Profile  = DeviceManager?.ShaderProfile ?? GraphicsDevice.Features.RequestedProfile;
            // Copy optimization/debug levels
            compilerParameters.EffectParameters.OptimizationLevel = effectCompilerParameters.OptimizationLevel;
            compilerParameters.EffectParameters.Debug             = effectCompilerParameters.Debug;

            var source          = GetShaderSource(effectName);
            var compiler        = EffectSystem.Compiler;
            var compilerResults = compiler.Compile(source, compilerParameters);

            // Watch the source code files
            var effectBytecodeCompilerResult = compilerResults.Bytecode.WaitForResult();

            if (effectBytecodeCompilerResult.CompilationLog.HasErrors)
            {
                foreach (var m in effectBytecodeCompilerResult.CompilationLog.Messages)
                {
                    if (TryGetFilePath(m, out string path))
                    {
                        directoryWatcher.Track(path);
                    }
                }
            }
            else
            {
                var bytecode = effectBytecodeCompilerResult.Bytecode;
                foreach (var type in bytecode.HashSources.Keys)
                {
                    // TODO: the "/path" is hardcoded, used in ImportStreamCommand and ShaderSourceManager. Find a place to share this correctly.
                    using (var pathStream = FileProvider.OpenStream(EffectCompilerBase.GetStoragePathFromShaderType(type) + "/path", VirtualFileMode.Open, VirtualFileAccess.Read))
                        using (var reader = new StreamReader(pathStream))
                        {
                            var path = reader.ReadToEnd();
                            directoryWatcher.Track(path);
                        }
                }
            }

            return(compilerResults);
        }
Пример #6
0
        public static IEffectCompiler CreateEffectCompiler(IVirtualFileProvider fileProvider, EffectSystem effectSystem = null, string packageName = null, EffectCompilationMode effectCompilationMode = EffectCompilationMode.Local, bool recordEffectRequested = false, TaskSchedulerSelector taskSchedulerSelector = null)
        {
            EffectCompilerBase compiler = null;

#if XENKO_EFFECT_COMPILER
            if ((effectCompilationMode & EffectCompilationMode.Local) != 0)
            {
                // Local allowed and available, let's use that
                compiler = new EffectCompiler(fileProvider)
                {
                    SourceDirectories = { EffectCompilerBase.DefaultSourceShaderFolder },
                };
            }
#endif

            // Nothing to do remotely
            bool needRemoteCompiler = (compiler == null && (effectCompilationMode & EffectCompilationMode.Remote) != 0);
            if (needRemoteCompiler || recordEffectRequested)
            {
                // Create the object that handles the connection
                var shaderCompilerTarget = new RemoteEffectCompilerClient(packageName);

                if (recordEffectRequested)
                {
                    // Let's notify effect compiler server for each new effect requested
                    effectSystem.EffectUsed += shaderCompilerTarget.NotifyEffectUsed;
                }

                // Use remote only if nothing else was found before (i.e. a local compiler)
                if (needRemoteCompiler)
                {
                    // Create a remote compiler
                    compiler = new RemoteEffectCompiler(fileProvider, shaderCompilerTarget);
                }
                else
                {
                    // Otherwise, EffectSystem takes ownership of shaderCompilerTarget
                    shaderCompilerTarget.DisposeBy(effectSystem);
                }
            }

            // Local not possible or allowed, and remote not allowed either => switch back to null compiler
            if (compiler == null)
            {
                compiler = new NullEffectCompiler(fileProvider);
            }

            return(new EffectCompilerCache(compiler, taskSchedulerSelector));
        }
Пример #7
0
        public override void Initialize()
        {
            base.Initialize();

            isInitialized = true;

            // Get graphics device service
            graphicsDeviceService = Services.GetSafeServiceAs <IGraphicsDeviceService>();

#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
            Enabled                    = true;
            directoryWatcher           = new DirectoryWatcher("*.pdxsl");
            directoryWatcher.Modified += FileModifiedEvent;
            // TODO: pdxfx too
#endif
            compiler = (EffectCompilerBase)CreateEffectCompiler();
        }
Пример #8
0
        internal static IEffectCompiler CreateEffectCompiler(EffectSystem effectSystem, Guid?packageId, EffectCompilationMode effectCompilationMode, bool recordEffectRequested, TaskSchedulerSelector taskSchedulerSelector = null)
        {
            EffectCompilerBase compiler = null;

#if SILICONSTUDIO_XENKO_EFFECT_COMPILER
            if ((effectCompilationMode & EffectCompilationMode.Local) != 0)
            {
                // Local allowed and available, let's use that
                compiler = new EffectCompiler
                {
                    SourceDirectories = { EffectCompilerBase.DefaultSourceShaderFolder },
                };
            }
#endif

            // Nothing to do remotely
            bool needRemoteCompiler = (compiler == null && (effectCompilationMode & EffectCompilationMode.Remote) != 0);
            if (needRemoteCompiler || recordEffectRequested)
            {
                // Create the object that handles the connection
                var shaderCompilerTarget = new RemoteEffectCompilerClient(packageId);

                if (recordEffectRequested)
                {
                    // Let's notify effect compiler server for each new effect requested
                    effectSystem.EffectUsed += shaderCompilerTarget.NotifyEffectUsed;
                }

                // Use remote only if nothing else was found before (i.e. a local compiler)
                if (needRemoteCompiler)
                {
                    // Create a remote compiler
                    compiler = new RemoteEffectCompiler(shaderCompilerTarget);
                }
            }

            // Local not possible or allowed, and remote not allowed either => switch back to null compiler
            if (compiler == null)
            {
                compiler = new NullEffectCompiler();
            }

            return(new EffectCompilerCache(compiler, taskSchedulerSelector));
        }
Пример #9
0
        public override void Initialize()
        {
            base.Initialize();

            // Create compiler
#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
            var effectCompiler = new Shaders.Compiler.EffectCompiler();
            effectCompiler.SourceDirectories.Add(EffectCompilerBase.DefaultSourceShaderFolder);

            Enabled                    = true;
            directoryWatcher           = new DirectoryWatcher("*.pdxsl");
            directoryWatcher.Modified += FileModifiedEvent;

            // TODO: pdxfx too
#else
            var effectCompiler = new NullEffectCompiler();
#endif
            compiler = new EffectCompilerCache(effectCompiler);
        }
Пример #10
0
        public static string GetPathOfSdslShader(string effectName, IVirtualFileProvider fileProvider, IVirtualFileProvider dbFileProvider = null)
        {
            var path = EffectCompilerBase.GetStoragePathFromShaderType(effectName);

            if (fileProvider.TryGetFileLocation(path, out var filePath, out _, out _))
            {
                if (File.Exists(filePath))
                {
                    return(filePath);
                }
            }

            var pathUrl = path + "/path";

            if (fileProvider.FileExists(pathUrl))
            {
                using (var pathStream = fileProvider.OpenStream(pathUrl, VirtualFileMode.Open, VirtualFileAccess.Read))
                    using (var reader = new StreamReader(pathStream))
                    {
                        var dbPath = reader.ReadToEnd();
                        if (File.Exists(dbPath))
                        {
                            return(dbPath);
                        }
                    }
            }

            if (dbFileProvider != null)
            {
                return(GetPathOfSdslShader(effectName, dbFileProvider));
            }

            //find locally
            if (LocalShaderFilePaths.TryGetValue(effectName, out var fp))
            {
                return(fp);
            }

            return(null);
        }
Пример #11
0
        public GameStudioBuilderService(SessionViewModel sessionViewModel, GameSettingsProviderService settingsProvider, string buildDirectory, bool createDebugTools = true)
            : base(buildDirectory)
        {
            this.createDebugTools = createDebugTools;
            if (createDebugTools)
            {
                assetBuilderServiceDebugPage   = EditorDebugTools.CreateLogDebugPage(GlobalLogger.GetLogger("AssetBuilderService"), "AssetBuilderService");
                effectCompilerServiceDebugPage = EditorDebugTools.CreateLogDebugPage(GlobalLogger.GetLogger("EffectCompilerCache"), "EffectCompilerCache");
            }

            SessionViewModel = sessionViewModel ?? throw new ArgumentNullException(nameof(sessionViewModel));

            var shaderImporter   = new StrideShaderImporter();
            var shaderBuildSteps = shaderImporter.CreateSystemShaderBuildSteps(sessionViewModel);

            shaderBuildSteps.StepProcessed += ShaderBuildStepsStepProcessed;
            PushBuildUnit(new PrecompiledAssetBuildUnit(AssetBuildUnitIdentifier.Default, shaderBuildSteps, true));

            Database = new GameStudioDatabase(this, settingsProvider);

            const string shaderBundleUrl = "/binary/editor/EditorShadersD3D11.bundle";

            if (VirtualFileSystem.FileExists(shaderBundleUrl))
            {
                Builder.ObjectDatabase.BundleBackend.LoadBundleFromUrl("EditorShadersD3D11", Builder.ObjectDatabase.ContentIndexMap, shaderBundleUrl, true).Wait();
            }

            // Use a shared database for our shader system
            // TODO: Shaders compiled on main thread won't actually be visible to MicroThread build engine (contentIndexMap are separate).
            // It will still work and cache because EffectCompilerCache caches not only at the index map level, but also at the database level.
            // Later, we probably want to have a GetSharedDatabase() allowing us to mutate it (or merging our results back with IndexFileCommand.AddToSharedGroup()),
            // so that database created with MountDatabase also have all the newest shaders.
            taskScheduler = new EffectPriorityScheduler(ThreadPriority.BelowNormal, Math.Max(1, Environment.ProcessorCount / 2));
            TaskSchedulerSelector taskSchedulerSelector = (mixinTree, compilerParameters) => taskScheduler.GetOrCreatePriorityGroup(compilerParameters?.TaskPriority ?? 0);

            effectCompiler = (EffectCompilerBase)EffectCompilerFactory.CreateEffectCompiler(MicrothreadLocalDatabases.GetSharedDatabase(), taskSchedulerSelector: taskSchedulerSelector);

            StartPushNotificationsTask();
        }
Пример #12
0
        /// <summary>
        /// Performs the maximal reduction.
        /// </summary>
        //public Dictionary<UFile, Image> Run(EffectCompilerBase compiler)
        public bool Run(EffectCompilerBase compiler)
        {
            var result = true;

            if (commandList.Count > 0)
            {
                if (plane == null)
                {
                    plane = GeometricPrimitive.Plane.New(graphicsDevice, 2.0f, 2.0f);
                }

                var assetManager = new AssetManager();
                assetManager.Serializer.RegisterSerializer(new GpuTextureSerializer2(graphicsDevice));

                var textures = new Dictionary <string, Graphics.Texture>();
                var materialTreeShaderCreator = new MaterialTreeShaderCreator(Material);
                var textureVisitor            = new MaterialTextureVisitor(Material);
                var compilerParameters        = new CompilerParameters {
                    Platform = GraphicsPlatform.Direct3D11, Profile = GraphicsProfile.Level_11_0
                };

                foreach (var command in commandList)
                {
                    var computeColorShader = materialTreeShaderCreator.GenerateShaderForReduction(command.OldNode);
                    if (computeColorShader == null)
                    {
                        continue;
                    }

                    var finalShader = new ShaderMixinSource();
                    finalShader.Mixins.Add(new ShaderClassSource("FlattenLayers"));
                    finalShader.Compositions.Add("outColor", computeColorShader);
                    var results = compiler.Compile(finalShader, compilerParameters);

                    if (results.HasErrors)
                    {
                        continue;
                    }

                    command.TreeEffect = new Graphics.Effect(graphicsDevice, results.MainBytecode, results.MainUsedParameters);
                    command.Parameters = new ParameterCollection();
                    var maxWidth    = 0;
                    var maxHeight   = 0;
                    var allTextures = textureVisitor.GetAllTextureValues(command.OldNode);
                    foreach (var texSlot in allTextures)
                    {
                        Graphics.Texture tex;
                        if (!textures.TryGetValue(texSlot.TextureName, out tex))
                        {
                            //TODO: change load so that texture can be unloaded.
                            tex = assetManager.Load <Graphics.Texture>(texSlot.TextureName);
                            textures.Add(texSlot.TextureName, tex);
                        }

                        if (tex == null)
                        {
                            throw new FileNotFoundException("Texture " + texSlot.TextureName + " not found");
                        }

                        command.Parameters.Set(texSlot.UsedParameterKey, tex);
                        maxWidth  = Math.Max(maxWidth, tex.ViewWidth);
                        maxHeight = Math.Max(maxHeight, tex.ViewHeight);
                        // can take min, a user-defined size, or clamp the min/max
                        // exclude mask?
                    }

                    command.RenderTarget = Graphics.Texture.New2D(graphicsDevice, maxWidth, maxHeight, PixelFormat.R8G8B8A8_UNorm, TextureFlags.ShaderResource | TextureFlags.RenderTarget);
                    command.ToExecute    = true;
                }

                // remove wrong commands
                commandList.RemoveAll(x => !x.ToExecute);

                var nodeReplacer = new MaterialNodeReplacer(Material);

                foreach (var command in commandList.Where(x => x.ToExecute))
                {
                    lock (graphicsDevice)
                    {
                        graphicsDevice.Clear(command.RenderTarget, Color4.Black);
                        graphicsDevice.SetRenderTarget(command.RenderTarget);

                        graphicsDevice.SetRasterizerState(graphicsDevice.RasterizerStates.CullNone);
                        graphicsDevice.SetDepthStencilState(graphicsDevice.DepthStencilStates.None);

                        command.TreeEffect.Apply(command.Parameters);
                        plane.Draw();

                        // save texture
                        SaveTexture(command.RenderTarget, command.TextureUrl, assetManager);
                    }
                    // make new tree
                    var newNode = new MaterialTextureNode(command.TextureUrl.FullPath, command.TexcoordIndex, Vector2.One, Vector2.Zero);

                    nodeReplacer.Replace(command.OldNode, newNode);

                    // save new material?
                    command.ToExecute = false;
                }

                foreach (var command in commandList)
                {
                    command.TreeEffect.Dispose();
                    command.RenderTarget.Dispose();
                }

                foreach (var texture in textures)
                {
                    texture.Value.Dispose();
                }
                textures.Clear();

                foreach (var tex in textures)
                {
                    assetManager.Unload(tex);
                }

                textures.Clear();
                result = commandList.All(x => !x.ToExecute);
                commandList.Clear();
            }

            return(result);
        }
Пример #13
0
        protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
        {
            var compiler = GetOrCreateEffectCompiler(context);

            // Get main effect name (before the first dot)
            var isSdfx = ShaderMixinManager.Contains(effectName);
            var source = isSdfx ?
                         new ShaderMixinGeneratorSource(effectName) :
                         (ShaderSource) new ShaderClassSource(effectName);

            int permutationCount;

            lock (PermutationCount)
            {
                PermutationCount.TryGetValue(effectName, out permutationCount);
                permutationCount++;
                PermutationCount[effectName] = permutationCount;
            }
            commandContext.Logger.Verbose($"Trying permutation #{permutationCount} for effect [{effectName}]: \n{compilerParameters.ToStringPermutationsDetailed()}");

            var compilerResults = compiler.Compile(source, compilerParameters);

            // Copy logs and if there are errors, exit directly
            compilerResults.CopyTo(commandContext.Logger);
            if (compilerResults.HasErrors)
            {
                return(Task.FromResult(ResultStatus.Failed));
            }

            // Wait for result an check compilation status
            var completedTask = compilerResults.Bytecode.WaitForResult();

            completedTask.CompilationLog.CopyTo(commandContext.Logger);
            if (completedTask.CompilationLog.HasErrors)
            {
                return(Task.FromResult(ResultStatus.Failed));
            }

            // Register all dependencies
            var allSources = new HashSet <string>(
                completedTask.Bytecode.HashSources.Select(keyPair => keyPair.Key));

            foreach (var className in allSources)
            {
                commandContext.RegisterInputDependency(new ObjectUrl(UrlType.Content, EffectCompilerBase.GetStoragePathFromShaderType(className)));
            }

            // Generate sourcecode if configured
            if (compilerParameters.ContainsKey(EffectSourceCodeKeys.Enable))
            {
                var outputDirectory = UPath.Combine(package.RootDirectory, baseUrl);

                var fieldName = compilerParameters.Get(EffectSourceCodeKeys.FieldName);
                if (fieldName.StartsWith("binary"))
                {
                    fieldName = fieldName.Substring("binary".Length);
                    if (char.IsUpper(fieldName[0]))
                    {
                        fieldName = char.ToLower(fieldName[0]) + fieldName.Substring(1);
                    }
                }

                var outputClassFile     = effectName + "." + fieldName + "." + compilerParameters.EffectParameters.Platform + "." + compilerParameters.EffectParameters.Profile + ".cs";
                var fullOutputClassFile = Path.Combine(outputDirectory.ToWindowsPath(), outputClassFile);

                commandContext.Logger.Verbose($"Writing shader bytecode to .cs source [{fullOutputClassFile}].");
                using (var stream = new FileStream(fullOutputClassFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                    EffectByteCodeToSourceCodeWriter.Write(effectName, compilerParameters, compilerResults.Bytecode.WaitForResult().Bytecode, new StreamWriter(stream, System.Text.Encoding.UTF8));
            }

            return(Task.FromResult(ResultStatus.Successful));
        }
Пример #14
0
        public ThumbnailGenerator(EffectCompilerBase effectCompiler)
        {
            // create base services
            Services = new ServiceRegistry();
            Services.AddService(MicrothreadLocalDatabases.ProviderService);
            ContentManager = new ContentManager(Services);
            Services.AddService <IContentManager>(ContentManager);
            Services.AddService(ContentManager);

            GraphicsDevice      = GraphicsDevice.New();
            GraphicsContext     = new GraphicsContext(GraphicsDevice);
            GraphicsCommandList = GraphicsContext.CommandList;
            Services.AddService(GraphicsContext);
            sceneSystem = new SceneSystem(Services);
            Services.AddService(sceneSystem);
            fontSystem = new GameFontSystem(Services);
            Services.AddService(fontSystem.FontSystem);
            Services.AddService <IFontFactory>(fontSystem.FontSystem);

            GraphicsDeviceService = new GraphicsDeviceServiceLocal(Services, GraphicsDevice);
            Services.AddService(GraphicsDeviceService);

            var uiSystem = new UISystem(Services);

            Services.AddService(uiSystem);

            var physicsSystem = new Bullet2PhysicsSystem(Services);

            Services.AddService <IPhysicsSystem>(physicsSystem);

            gameSystems = new GameSystemCollection(Services)
            {
                fontSystem, uiSystem, physicsSystem
            };
            Services.AddService <IGameSystemCollection>(gameSystems);
            Simulation.DisableSimulation = true; //make sure we do not simulate physics within the editor

            // initialize base services
            gameSystems.Initialize();

            // create remaining services
            EffectSystem = new EffectSystem(Services);
            Services.AddService(EffectSystem);

            gameSystems.Add(EffectSystem);
            gameSystems.Add(sceneSystem);
            EffectSystem.Initialize();

            // Mount the same database for the cache
            EffectSystem.Compiler = EffectCompilerFactory.CreateEffectCompiler(effectCompiler.FileProvider, EffectSystem);

            // Deactivate the asynchronous effect compilation
            ((EffectCompilerCache)EffectSystem.Compiler).CompileEffectAsynchronously = false;

            // load game system content
            gameSystems.LoadContent();

            // create the default fonts
            var fontItem = OfflineRasterizedSpriteFontFactory.Create();

            fontItem.FontType.Size = 22;
            DefaultFont            = OfflineRasterizedFontCompiler.Compile(fontSystem.FontSystem, fontItem, true);

            // create utility members
            nullGameTime = new GameTime();
            SpriteBatch  = new SpriteBatch(GraphicsDevice);
            UIBatch      = new UIBatch(GraphicsDevice);

            // create the pipeline
            SetUpPipeline();
        }
Пример #15
0
        protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
        {
            var compiler = GetOrCreateEffectCompiler(context);

            // Get main effect name (before the first dot)
            var isPdxfx = ShaderMixinManager.Contains(effectName);
            var source  = isPdxfx ? new ShaderMixinGeneratorSource(effectName) : (ShaderSource) new ShaderClassSource(effectName);

            int permutationCount;

            lock (PermutationCount)
            {
                PermutationCount.TryGetValue(effectName, out permutationCount);
                permutationCount++;
                PermutationCount[effectName] = permutationCount;
            }
            commandContext.Logger.Info("Trying permutation #{0} for effect [{1}]: \n{2}", permutationCount, effectName, compilerParameters.ToStringDetailed());

            var compilerResults = compiler.Compile(source, compilerParameters);

            // Copy logs and if there are errors, exit directlry
            compilerResults.CopyTo(commandContext.Logger);
            if (compilerResults.HasErrors)
            {
                return(Task.FromResult(ResultStatus.Failed));
            }

            // Register all dependencies
            var allSources = new HashSet <string>(compilerResults.Bytecode.WaitForResult().Bytecode.HashSources.Select(keyPair => keyPair.Key));

            foreach (var className in allSources)
            {
                commandContext.RegisterInputDependency(new ObjectUrl(UrlType.Internal, EffectCompilerBase.GetStoragePathFromShaderType(className)));
            }

            // Generate sourcecode if configured
            if (compilerParameters.ContainsKey(EffectSourceCodeKeys.Enable))
            {
                var outputDirectory     = UPath.Combine(context.Package.RootDirectory, baseUrl);
                var outputClassFile     = effectName + ".bytecode." + compilerParameters.Platform + "." + compilerParameters.Profile + ".cs";
                var fullOutputClassFile = Path.Combine(outputDirectory.ToWindowsPath(), outputClassFile);

                commandContext.Logger.Info("Writing shader bytecode to .cs source [{0}]", fullOutputClassFile);
                using (var stream = new FileStream(fullOutputClassFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                    EffectByteCodeToSourceCodeWriter.Write(effectName, compilerParameters, compilerResults.Bytecode.WaitForResult().Bytecode, new StreamWriter(stream, System.Text.Encoding.UTF8));
            }

            return(Task.FromResult(ResultStatus.Successful));
        }