public void CompressTest(string file, Xenko.Graphics.PixelFormat format) { TexImage image = TestTools.Load(library, file); TexLibraryTest.CompressTest(image, library, format); image.Dispose(); }
internal ShaderCompilationContext ParseAndAnalyze(ShaderMixinSource shaderMixinSource, Xenko.Shaders.ShaderMacro[] macros, out ShaderMixinParsingResult parsingResult, out HashSet<ModuleMixinInfo> mixinsToAnalyze) { // Creates a parsing result parsingResult = new ShaderMixinParsingResult(); SiliconStudio.Shaders.Parser.ShaderMacro[] macrosParser; if (macros == null) { macrosParser = new SiliconStudio.Shaders.Parser.ShaderMacro[0]; } else { macrosParser = new SiliconStudio.Shaders.Parser.ShaderMacro[macros.Length]; for (var i = 0; i < macros.Length; ++i) macrosParser[i] = new SiliconStudio.Shaders.Parser.ShaderMacro(macros[i].Name, macros[i].Definition); } //PerformanceLogger.Start(PerformanceStage.Global); // ---------------------------------------------------------- // Load all shaders // ---------------------------------------------------------- lock (shaderLibrary) { //PerformanceLogger.Start(PerformanceStage.Loading); mixinsToAnalyze = shaderLibrary.LoadShaderSource(shaderMixinSource, macrosParser); //PerformanceLogger.Stop(PerformanceStage.Loading); } // Extract all ModuleMixinInfo and check for any errors var allMixinInfos = new HashSet<ModuleMixinInfo>(); foreach (var moduleMixinInfo in mixinsToAnalyze) { allMixinInfos.UnionWith(moduleMixinInfo.MinimalContext); } foreach (var moduleMixinInfo in allMixinInfos) { moduleMixinInfo.Log.CopyTo(parsingResult); var ast = moduleMixinInfo.MixinAst; var shaderClassSource = moduleMixinInfo.ShaderSource as ShaderClassSource; // If we have a ShaderClassSource and it is not an inline one, then we can store the hash sources if (ast != null && shaderClassSource != null) { parsingResult.HashSources[shaderClassSource.ClassName] = moduleMixinInfo.SourceHash; } } // Return directly if there was any errors if (parsingResult.HasErrors) return null; // ---------------------------------------------------------- // Perform Type Analysis // ---------------------------------------------------------- //PerformanceLogger.Start(PerformanceStage.TypeAnalysis); var context = GetCompilationContext(mixinsToAnalyze, parsingResult); //PerformanceLogger.Stop(PerformanceStage.TypeAnalysis); // Return directly if there was any errors if (parsingResult.HasErrors) return context; lock (SemanticAnalyzerLock) { //PerformanceLogger.Start(PerformanceStage.SemanticAnalysis); //SemanticPerformance.Start(SemanticStage.Global); foreach (var mixin in mixinsToAnalyze) context.Analyze(mixin); //SemanticPerformance.Pause(SemanticStage.Global); //PerformanceLogger.Stop(PerformanceStage.SemanticAnalysis); } return context; }
/// <summary> /// Mixes shader parts to produces a single HLSL file shader. /// </summary> /// <param name="shaderMixinSource">The shader source.</param> /// <param name="macros">The shader perprocessor macros.</param> /// <param name="modifiedShaders">The list of modified shaders.</param> /// <returns>The combined shader in AST form.</returns> public ShaderMixinParsingResult Parse(ShaderMixinSource shaderMixinSource, Xenko.Shaders.ShaderMacro[] macros = null) { // Creates a parsing result HashSet<ModuleMixinInfo> mixinsToAnalyze; ShaderMixinParsingResult parsingResult; var context = ParseAndAnalyze(shaderMixinSource, macros, out parsingResult, out mixinsToAnalyze); // Return directly if there was any errors if (parsingResult.HasErrors) return parsingResult; // Update the clone context in case new instances of classes are created CloneContext mixCloneContext; lock (hlslCloneContext) { HlslSemanticAnalysis.UpdateCloneContext(hlslCloneContext); mixCloneContext = new CloneContext(hlslCloneContext); } // only clone once the stage classes foreach (var mixinInfo in mixinsToAnalyze) { foreach (var mixin in mixinInfo.Mixin.MinimalContext.Where(x => x.StageOnlyClass)) { mixin.DeepClone(mixCloneContext); } } // ---------------------------------------------------------- // Perform Shader Mixer // ---------------------------------------------------------- var externDict = new CompositionDictionary(); var finalModuleList = BuildCompositionsDictionary(shaderMixinSource, externDict, context, mixCloneContext, parsingResult); //PerformanceLogger.Stop(PerformanceStage.DeepClone); if (parsingResult.HasErrors) return parsingResult; // look for stage compositions and add the links between variables and compositions when necessary var extraExternDict = new Dictionary<Variable, List<ModuleMixin>>(); foreach (var item in externDict) { if (item.Key.Qualifiers.Contains(XenkoStorageQualifier.Stage)) FullLinkStageCompositions(item.Key, item.Value, externDict, extraExternDict, parsingResult); } foreach (var item in extraExternDict) externDict.Add(item.Key, item.Value); var mixinDictionary = BuildMixinDictionary(finalModuleList); if (finalModuleList != null) { var finalModule = finalModuleList[0]; //PerformanceLogger.Start(PerformanceStage.Mix); var mixer = new XenkoShaderMixer(finalModule, parsingResult, mixinDictionary, externDict, new CloneContext(mixCloneContext)); mixer.Mix(); //PerformanceLogger.Stop(PerformanceStage.Mix); // Return directly if there was any errors if (parsingResult.HasErrors) return parsingResult; var finalShader = mixer.GetMixedShader(); // Simplifies the shader by removing dead code var simplifier = new ExpressionSimplifierVisitor(); simplifier.Run(finalShader); parsingResult.Reflection = new EffectReflection(); var xkShaderLinker = new ShaderLinker(parsingResult); xkShaderLinker.Run(finalShader); // Return directly if there was any errors if (parsingResult.HasErrors) return parsingResult; // Find all entry points // TODO: make this configurable by CompileParameters foreach (var stage in new[] {ShaderStage.Compute, ShaderStage.Vertex, ShaderStage.Hull, ShaderStage.Domain, ShaderStage.Geometry, ShaderStage.Pixel}) { var entryPoint = finalShader.Declarations.OfType<MethodDefinition>().FirstOrDefault(f => f.Attributes.OfType<AttributeDeclaration>().Any(a => a.Name == "EntryPoint" && (string)a.Parameters[0].Value == stage.ToString())); if (entryPoint == null) { continue; } parsingResult.EntryPoints[stage] = entryPoint.Name.Text; // When this is a compute shader, there is no need to scan other stages if (stage == ShaderStage.Compute) break; } var typeCleaner = new XenkoShaderCleaner(); typeCleaner.Run(finalShader); //PerformanceLogger.Stop(PerformanceStage.Global); //PerformanceLogger.PrintLastResult(); //SemanticPerformance.PrintResult(); //MixPerformance.PrintResult(); //GenerateShaderPerformance.PrintResult(); //StreamCreatorPerformance.PrintResult(); //ShaderLoader.PrintTime(); //PerformanceLogger.WriteOut(52); parsingResult.Shader = finalShader; } return parsingResult; }
/// <summary> /// Initializes a new instance of the <see cref="LoadingRequest"/> class to load a texture from a <see cref="SiliconStudio.Xenko.Graphics.Image"/> instance. /// </summary> /// <param name="image">The image.</param> /// <param name="loadAsSRgb">Indicate if the input file should be loaded as in sRGB file</param> public LoadingRequest(Xenko.Graphics.Image image, bool loadAsSRgb) { XkImage = image; Mode = LoadingMode.XkImage; LoadAsSRgb = loadAsSRgb; }