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) };