Пример #1
0
        private CompilerResults GetCompilerResults(string effectName, CompilerParameters compilerParameters)
        {
            compilerParameters.Profile = GraphicsDevice.ShaderProfile.HasValue ? GraphicsDevice.ShaderProfile.Value : GraphicsDevice.Features.Profile;
#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLCORE
            compilerParameters.Platform = GraphicsPlatform.OpenGL;
#endif
#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
            compilerParameters.Platform = GraphicsPlatform.OpenGLES;
#endif

            // Compile shader
            var isXkfx = ShaderMixinManager.Contains(effectName);

            // 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 (isXkfx)
            {
                // perform an early test only based on the parameters
                compilerResult = GetShaderFromParameters(effectName, compilerParameters);
            }

            if (compilerResult == null)
            {
                var source = isXkfx ? new ShaderMixinGeneratorSource(effectName) : (ShaderSource) new ShaderClassSource(effectName);
                compilerResult = compiler.Compile(source, compilerParameters);

                var effectRequested = EffectUsed;
                if (effectRequested != null)
                {
                    effectRequested(new EffectCompileRequest(effectName, compilerResult.UsedParameters));
                }

                if (!compilerResult.HasErrors && isXkfx)
                {
                    lock (earlyCompilerCache)
                    {
                        List <CompilerResults> effectCompilerResults;
                        if (!earlyCompilerCache.TryGetValue(effectName, out effectCompilerResults))
                        {
                            effectCompilerResults = new List <CompilerResults>();
                            earlyCompilerCache.Add(effectName, 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);
        }
Пример #2
0
        private CompilerResults GetCompilerResults(string effectName, CompilerParameters compilerParameters)
        {
            // Compile shader
            var isXkfx = ShaderMixinManager.Contains(effectName);

            // 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 (isXkfx)
            {
                // perform an early test only based on the parameters
                compilerResult = GetShaderFromParameters(effectName, compilerParameters);
            }

            if (compilerResult == null)
            {
                var effectRequested = EffectUsed;
                if (effectRequested != null)
                {
                    effectRequested(new EffectCompileRequest(effectName, new CompilerParameters(compilerParameters)));
                }

                var source = isXkfx ? new ShaderMixinGeneratorSource(effectName) : (ShaderSource) new ShaderClassSource(effectName);
                compilerResult = compiler.Compile(source, compilerParameters);

                if (!compilerResult.HasErrors && isXkfx)
                {
                    lock (earlyCompilerCache)
                    {
                        List <CompilerResults> effectCompilerResults;
                        if (!earlyCompilerCache.TryGetValue(effectName, out effectCompilerResults))
                        {
                            effectCompilerResults = new List <CompilerResults>();
                            earlyCompilerCache.Add(effectName, 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);
        }
Пример #3
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);
        }
Пример #4
0
        private CompilerResults GetCompilerResults(string effectName, CompilerParameters compilerParameters)
        {
            compilerParameters.Profile = GraphicsDevice.ShaderProfile.HasValue ? GraphicsDevice.ShaderProfile.Value : 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

            // Compile shader
            var isPdxfx = ShaderMixinManager.Contains(effectName);

            // 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(effectName, compilerParameters);
            }

            if (compilerResult == null)
            {
                var source = isPdxfx ? new ShaderMixinGeneratorSource(effectName) : (ShaderSource) new ShaderClassSource(effectName);
                compilerResult = compiler.Compile(source, compilerParameters);

#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
                // If enabled, request this effect compile
                // TODO: For now we save usedParameters, but ideally we probably want to have a list of everything that might be use by a given
                //       pdxfx and filter against this, so that branches not taken on a specific situation/platform can still be reproduced on another.
                // Alternatively, we could save full compilerParameters, but we would have to ignore certain things that are not serializable, such as Texture.
                lock (effectCompileRecordLock)
                {
                    if (recordedEffectCompile != null)
                    {
                        var effectCompileRequest = new EffectCompileRequest(effectName, compilerResult.UsedParameters);
                        if (!recordedEffectCompile.Contains(effectCompileRequest))
                        {
                            recordedEffectCompile[effectCompileRequest] = true;
                        }
                    }
                }
#endif

                if (!compilerResult.HasErrors && isPdxfx)
                {
                    lock (earlyCompilerCache)
                    {
                        List <CompilerResults> effectCompilerResults;
                        if (!earlyCompilerCache.TryGetValue(effectName, out effectCompilerResults))
                        {
                            effectCompilerResults = new List <CompilerResults>();
                            earlyCompilerCache.Add(effectName, 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);
        }