From 04da13438c0ad980293a6f746c7cd35fafd8d59c Mon Sep 17 00:00:00 2001 From: Pedro413 <44695680+Pedro413@users.noreply.github.com> Date: Tue, 30 Apr 2024 11:30:01 +1000 Subject: [PATCH] add explicit groups to recompileshaders --- .../Commands/Shaders/GenerateShaderCommand.cs | 26 +++++ .../Shaders/RecompileShadersCommand.cs | 102 ++++++++++++++++++ .../ShaderGenerator/ShaderGenerator.cs | 15 ++- 3 files changed, 140 insertions(+), 3 deletions(-) diff --git a/TagTool/Commands/Shaders/GenerateShaderCommand.cs b/TagTool/Commands/Shaders/GenerateShaderCommand.cs index 25addb1d..f721a24a 100644 --- a/TagTool/Commands/Shaders/GenerateShaderCommand.cs +++ b/TagTool/Commands/Shaders/GenerateShaderCommand.cs @@ -604,6 +604,16 @@ public struct STemplateRecompileInfo public RenderMethodTemplate Template; } + public struct SExplicitRecompileInfo + { + public CachedTag PixelTag; + public CachedTag VertexTag; + public bool IsChud; + public PixelShader PixelShader; + public VertexShader VertexShader; + public string ExplicitName; + } + /// /// For async recompile /// @@ -910,5 +920,21 @@ public static STemplateRecompileInfo GenerateRenderMethodTemplateAsync(GameCache return recompileInfo; } + + public static SExplicitRecompileInfo GenerateExplicitShaderAsync(GameCache cache, SExplicitRecompileInfo info) + { + Stream fakeStream = null;// unused atm + + if (info.IsChud) + { + ShaderGeneratorNew.GenerateChudShader(cache, fakeStream, info.ExplicitName, out info.PixelShader, out info.VertexShader); + } + else + { + ShaderGeneratorNew.GenerateExplicitShader(cache, fakeStream, info.ExplicitName, out info.PixelShader, out info.VertexShader); + } + + return info; + } } } diff --git a/TagTool/Commands/Shaders/RecompileShadersCommand.cs b/TagTool/Commands/Shaders/RecompileShadersCommand.cs index 67dfd794..3b699837 100644 --- a/TagTool/Commands/Shaders/RecompileShadersCommand.cs +++ b/TagTool/Commands/Shaders/RecompileShadersCommand.cs @@ -31,6 +31,18 @@ public RecompileShadersCommand(GameCache cache) : Cache = cache; } + private static Dictionary> ExplicitShaderGroups = new Dictionary> + { + { "decorator", new List { "decorator_default", "decorator_no_wind", "decorator_shaded", "decorator_static", "decorator_sun", "decorator_wavy" } }, + { "chud", new List { "chud_cortana_camera", "chud_cortana_composite", "chud_cortana_offscreen", "chud_cortana_screen", "chud_cortana_screen_final", + "chud_crosshair", "chud_directional_damage", "chud_directional_damage_apply", "chud_double_gradient", "chud_emblem", "chud_medal", "chud_meter", + "chud_meter_chapter", "chud_meter_gradient", "chud_meter_shield", "chud_meter_single_color", "chud_navpoint", "chud_radial_gradient", + "chud_really_simple", "chud_sensor", "chud_simple", "chud_solid", "chud_text_simple", "chud_texture_cam", "chud_turbulence" } }, + { "shadow_apply", new List { "shadow_apply", "shadow_apply_bilinear", "shadow_apply_fancy", "shadow_apply_faster", "shadow_apply_point", } }, + { "final_composite", new List { "final_composite", "final_composite_debug", "final_composite_dof", "final_composite_zoom" } }, + { "displacement", new List { "displacement", "displacement_motion_blur" } }, + }; + public override object Execute(List args) { using (var stream = Cache.OpenCacheReadWrite()) @@ -38,6 +50,10 @@ public override object Execute(List args) if (args.Count > 0) { string shaderType = args[0].ToLower(); + + if (ExplicitShaderGroups.ContainsKey(shaderType)) + return RecompileExplicitShaderGroup(stream, shaderType); + return RecompileShaderTypeAsync(stream, shaderType); } else @@ -51,6 +67,92 @@ public override object Execute(List args) return true; } + private object RecompileExplicitShaderGroup(Stream stream, string shaderType) + { + var shaderList = ExplicitShaderGroups[shaderType]; + + List recompileInfo = new List(); + + if (shaderType == "chud") + { + var chgd = Cache.Deserialize(stream, Cache.TagCache.FindFirstInGroup("chgd")); + + for (int i = 0; i < chgd.HudShaders.Count-1; i++) // skip last as it is HO only + { + SExplicitRecompileInfo info = new SExplicitRecompileInfo + { + IsChud = true, + PixelTag = chgd.HudShaders[i].PixelShader, + VertexTag = chgd.HudShaders[i].VertexShader, + ExplicitName = chgd.HudShaders[i].PixelShader.Name.Split('\\').Last(), + }; + recompileInfo.Add(info); + } + } + else + { + foreach (var explicitShader in shaderList) + { + SExplicitRecompileInfo info = new SExplicitRecompileInfo(); + + if (!Cache.TagCache.TryGetTag($"rasterizer\\shaders\\{explicitShader}.pixl", out info.PixelTag) || + !Cache.TagCache.TryGetTag($"rasterizer\\shaders\\{explicitShader}.vtsh", out info.VertexTag)) + { + new TagToolError(CommandError.CustomMessage, $"Explicit shader {explicitShader} could not be found (skipping)"); + } + else + { + info.IsChud = false; + info.ExplicitName = explicitShader; + recompileInfo.Add(info); + } + } + } + + List> tasks = new List>(); + + foreach (var info in recompileInfo) + { + Task generatorTask = Task.Run(() => { + return GenerateExplicitShaderAsync(Cache, info); + }); + tasks.Add(generatorTask); + } + + float percentageComplete = 0.00f; + Console.Write($"\rRecompiling {shaderType} shaders... {string.Format("{0:0.00}", percentageComplete)}%"); + + int completed = 0; + while (completed != tasks.Count) + { + int count = tasks.FindAll(x => x.IsCompleted).Count; + if (count > completed) + { + completed = count; + + percentageComplete = ((float)count / (float)tasks.Count) * 100.0f; + Console.Write($"\rRecompiling {shaderType} templates... {string.Format("{0:0.00}", percentageComplete)}%"); + } + + System.Threading.Thread.Sleep(100); // wait to prevent constant cli writes + } + + Console.Write($"\rSuccessfully recompiled {tasks.Count} {shaderType} templates. Serializing..."); + + // serialize + foreach (var task in tasks) + { + Cache.Serialize(stream, task.Result.PixelTag, task.Result.PixelShader); + Cache.Serialize(stream, task.Result.VertexTag, task.Result.VertexShader); + (Cache as GameCacheHaloOnlineBase).SaveTagNames(); + } + + Console.Write($"\rSuccessfully recompiled {tasks.Count} {shaderType} shaders. Serializing... Done"); + Console.WriteLine(); + + return true; + } + private object RecompileShaderTypeAsync(Stream stream, string shaderType) { if (!Cache.TagCache.TryGetTag($"shaders\\{shaderType}.rmdf", out CachedTag rmdfTag)) diff --git a/TagTool/Shaders/ShaderGenerator/ShaderGenerator.cs b/TagTool/Shaders/ShaderGenerator/ShaderGenerator.cs index a22f1560..65639a3b 100644 --- a/TagTool/Shaders/ShaderGenerator/ShaderGenerator.cs +++ b/TagTool/Shaders/ShaderGenerator/ShaderGenerator.cs @@ -1675,10 +1675,19 @@ public static void GenerateChudShader(GameCache cache, Stream stream, string chu //ChudShader eChudShader = (ChudShader)Enum.Parse(typeof(ChudShader), chudShader, true); List supportedEntries = new List { ShaderStage.Default }; - if (chudShader == "chud_turbulence") + + switch (chudShader) { - supportedEntries.Add(ShaderStage.Albedo); - supportedEntries.Add(ShaderStage.Dynamic_Light); + case "chud_turbulence": + supportedEntries.Add(ShaderStage.Albedo); + supportedEntries.Add(ShaderStage.Dynamic_Light); + break; + case "chud_double_gradient": // ??? + chudShader = "chud_meter_double_gradient"; + break; + case "chud_radial_gradient": // ??? + chudShader = "chud_meter_radial_gradient"; + break; } List supportedVertices = new List { (chudShader == "chud_sensor" ? VertexType.FancyChud : VertexType.SimpleChud) };