Ejemplo n.º 1
0
        private void Init()
        {
            // Create and mount database file system
            var objDatabase          = ObjectDatabase.CreateDefaultDatabase();
            var databaseFileProvider = new DatabaseFileProvider(objDatabase);

            shaderMixinParser = new ShaderMixinParser(databaseFileProvider);
            shaderMixinParser.SourceManager.LookupDirectoryList.Add("/shaders");
        }
Ejemplo n.º 2
0
        public void Init()
        {
            // Create and mount database file system
            var objDatabase          = new ObjectDatabase("/data/db", "index", "/local/db");
            var databaseFileProvider = new DatabaseFileProvider(objDatabase);

            AssetManager.GetFileProvider = () => databaseFileProvider;

            shaderMixinParser = new ShaderMixinParser(AssetManager.FileProvider);
            shaderMixinParser.SourceManager.LookupDirectoryList.Add("/shaders");
        }
Ejemplo n.º 3
0
 private ShaderMixinParser GetMixinParser()
 {
     lock (shaderMixinParserLock)
     {
         // Generate the AST from the mixin description
         if (shaderMixinParser == null)
         {
             shaderMixinParser = new ShaderMixinParser(FileProvider ?? ContentManager.FileProvider);
             shaderMixinParser.SourceManager.LookupDirectoryList.AddRange(SourceDirectories); // TODO: temp
             shaderMixinParser.SourceManager.UseFileSystem = UseFileSystem;
             shaderMixinParser.SourceManager.UrlToFilePath = UrlToFilePath;                   // TODO: temp
         }
         return(shaderMixinParser);
     }
 }
Ejemplo n.º 4
0
        public void Init()
        {
            using (var profile = Profiler.Begin(GameProfilingKeys.ObjectDatabaseInitialize))
            {
                // Create and mount database file system
                var objDatabase          = new ObjectDatabase("/data/db", "index", "/local/db");
                var databaseFileProvider = new DatabaseFileProvider(objDatabase);
                AssetManager.GetFileProvider = () => databaseFileProvider;
            }

            sourceManager = new ShaderSourceManager();
            sourceManager.LookupDirectoryList.Add(@"shaders");
            shaderLoader      = new ShaderLoader(sourceManager);
            shaderMixinParser = new ShaderMixinParser();
            shaderMixinParser.SourceManager.LookupDirectoryList.Add(@"shaders");
        }
Ejemplo n.º 5
0
        public override EffectBytecode Compile(ShaderMixinSource shaderMixinSource, string fullEffectName, ShaderMixinParameters compilerParameters, HashSet <string> modifiedShaders, HashSet <string> recentlyModifiedShaders, LoggerResult log)
        {
            // Load D3D compiler dll
            // Note: No lock, it's probably fine if it gets called from multiple threads at the same time.
            if (Platform.IsWindowsDesktop && !d3dcompilerLoaded)
            {
                NativeLibrary.PreloadLibrary("d3dcompiler_47.dll");
                d3dcompilerLoaded = true;
            }

            // Make a copy of shaderMixinSource. Use deep clone since shaderMixinSource can be altered during compilation (e.g. macros)
            var shaderMixinSourceCopy = new ShaderMixinSource();

            shaderMixinSourceCopy.DeepCloneFrom(shaderMixinSource);

            shaderMixinSource = shaderMixinSourceCopy;

            // Generate platform-specific macros
            var platform = compilerParameters.Get(CompilerParameters.GraphicsPlatformKey);

            switch (platform)
            {
            case GraphicsPlatform.Direct3D11:
                shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_API_DIRECT3D", 1);
                shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_API_DIRECT3D11", 1);
                break;

            case GraphicsPlatform.OpenGL:
                shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGL", 1);
                shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLCORE", 1);
                break;

            case GraphicsPlatform.OpenGLES:
                shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGL", 1);
                shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES", 1);
                break;

            default:
                throw new NotSupportedException();
            }

            // Generate the AST from the mixin description
            if (shaderMixinParser == null)
            {
                shaderMixinParser = new ShaderMixinParser();
                shaderMixinParser.SourceManager.LookupDirectoryList = SourceDirectories; // TODO: temp
                shaderMixinParser.SourceManager.UrlToFilePath       = UrlToFilePath;     // TODO: temp
            }

            if (recentlyModifiedShaders != null && recentlyModifiedShaders.Count > 0)
            {
                shaderMixinParser.DeleteObsoleteCache(GetShaderNames(recentlyModifiedShaders));
                recentlyModifiedShaders.Clear();
            }
            var parsingResult = shaderMixinParser.Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray(), modifiedShaders);

            // Copy log from parser results to output
            CopyLogs(parsingResult, log);

            // Return directly if there are any errors
            if (parsingResult.HasErrors)
            {
                return(null);
            }

            // Convert the AST to HLSL
            var writer = new SiliconStudio.Shaders.Writer.Hlsl.HlslWriter {
                EnablePreprocessorLine = false
            };

            writer.Visit(parsingResult.Shader);
            var shaderSourceText = writer.Text;

            // -------------------------------------------------------
            // Save shader log
            // TODO: TEMP code to allow debugging generated shaders on Windows Desktop
#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
            var shaderId = ObjectId.FromBytes(Encoding.UTF8.GetBytes(shaderSourceText));

            var logDir = "log";
            if (!Directory.Exists(logDir))
            {
                Directory.CreateDirectory(logDir);
            }
            var shaderSourceFilename = Path.Combine(logDir, "shader_" + shaderId);
            lock (WriterLock) // protect write in case the same shader is created twice
            {
                if (!File.Exists(shaderSourceFilename))
                {
                    var builder = new StringBuilder();
                    builder.AppendLine("/***** Used Parameters *****");
                    builder.Append(" * EffectName: ");
                    builder.AppendLine(fullEffectName ?? "");
                    WriteParameters(builder, compilerParameters, 0, false);
                    builder.AppendLine(" ***************************/");
                    builder.Append(shaderSourceText);
                    File.WriteAllText(shaderSourceFilename, builder.ToString());
                }
            }
#endif
            // -------------------------------------------------------

            var bytecode = new EffectBytecode {
                Reflection = parsingResult.Reflection, HashSources = parsingResult.HashSources
            };

            // Select the correct backend compiler
            IShaderCompiler compiler;
            switch (platform)
            {
            case GraphicsPlatform.Direct3D11:
                compiler = new Direct3D.ShaderCompiler();
                break;

            case GraphicsPlatform.OpenGL:
            case GraphicsPlatform.OpenGLES:
                compiler = new OpenGL.ShaderCompiler();
                break;

            default:
                throw new NotSupportedException();
            }

            var shaderStageBytecodes = new List <ShaderBytecode>();

            foreach (var stageBinding in parsingResult.EntryPoints)
            {
                // Compile
                var result = compiler.Compile(shaderSourceText, stageBinding.Value, stageBinding.Key, compilerParameters, bytecode.Reflection, shaderSourceFilename);
                result.CopyTo(log);

                if (result.HasErrors)
                {
                    continue;
                }

                // -------------------------------------------------------
                // Append bytecode id to shader log
#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
                lock (WriterLock) // protect write in case the same shader is created twice
                {
                    if (File.Exists(shaderSourceFilename))
                    {
                        // Append at the end of the shader the bytecodes Id
                        File.AppendAllText(shaderSourceFilename, "\n// {0} {1}".ToFormat(stageBinding.Key, result.Bytecode.Id));
                    }
                }
#endif
                // -------------------------------------------------------

                shaderStageBytecodes.Add(result.Bytecode);

                // When this is a compute shader, there is no need to scan other stages
                if (stageBinding.Key == ShaderStage.Compute)
                {
                    break;
                }
            }

            // Get the current time of compilation
            bytecode.Time = DateTime.Now;

            // In case of Direct3D, we can safely remove reflection data as it is entirely resolved at compile time.
            if (platform == GraphicsPlatform.Direct3D11)
            {
                CleanupReflection(bytecode.Reflection);
            }

            bytecode.Stages = shaderStageBytecodes.ToArray();
            return(bytecode);
        }