From 4fcc549f995f1611033e4e0315591696971b7e6a Mon Sep 17 00:00:00 2001 From: Razmoth <32140579+Razmoth@users.noreply.github.com> Date: Tue, 19 Sep 2023 15:41:22 +0400 Subject: [PATCH] - [Core] Fix issue with exporting/previewing new shader foramt [GI] --- AssetStudio/Classes/Shader.cs | 8 +++---- AssetStudioCLI/Exporter.cs | 2 +- AssetStudioGUI/AssetStudioGUIForm.cs | 2 +- AssetStudioGUI/Exporter.cs | 2 +- AssetStudioUtility/ShaderConverter.cs | 31 ++++++++++++++++++--------- 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/AssetStudio/Classes/Shader.cs b/AssetStudio/Classes/Shader.cs index 9a99a49..0bc6eef 100644 --- a/AssetStudio/Classes/Shader.cs +++ b/AssetStudio/Classes/Shader.cs @@ -578,8 +578,8 @@ namespace AssetStudio public UAVParameter[] m_UAVParams; public SamplerParameter[] m_Samplers; - private static bool HasGlobalLocalKeywordIndices(ObjectReader reader) => reader.serializedType.Match("E99740711222CD922E9A6F92FF1EB07A") || reader.serializedType.Match("450A058C218DAF000647948F2F59DA6D"); - private static bool HasInstancedStructuredBuffers(ObjectReader reader) => reader.serializedType.Match("E99740711222CD922E9A6F92FF1EB07A"); + public static bool HasGlobalLocalKeywordIndices(SerializedType type) => type.Match("E99740711222CD922E9A6F92FF1EB07A") || type.Match("450A058C218DAF000647948F2F59DA6D"); + public static bool HasInstancedStructuredBuffers(SerializedType type) => type.Match("E99740711222CD922E9A6F92FF1EB07A"); public SerializedSubProgram(ObjectReader reader) { @@ -588,7 +588,7 @@ namespace AssetStudio m_BlobIndex = reader.ReadUInt32(); m_Channels = new ParserBindChannels(reader); - if ((version[0] >= 2019 && version[0] < 2021) || (version[0] == 2021 && version[1] < 2) || HasGlobalLocalKeywordIndices(reader)) //2019 ~2021.1 + if ((version[0] >= 2019 && version[0] < 2021) || (version[0] == 2021 && version[1] < 2) || HasGlobalLocalKeywordIndices(reader.serializedType)) //2019 ~2021.1 { var m_GlobalKeywordIndices = reader.ReadUInt16Array(); reader.AlignStream(); @@ -690,7 +690,7 @@ namespace AssetStudio } } - if (HasInstancedStructuredBuffers(reader)) + if (HasInstancedStructuredBuffers(reader.serializedType)) { int numInstancedStructuredBuffers = reader.ReadInt32(); var m_InstancedStructuredBuffers = new ConstantBuffer[numInstancedStructuredBuffers]; diff --git a/AssetStudioCLI/Exporter.cs b/AssetStudioCLI/Exporter.cs index 7b3a1bc..a27b031 100644 --- a/AssetStudioCLI/Exporter.cs +++ b/AssetStudioCLI/Exporter.cs @@ -69,7 +69,7 @@ namespace AssetStudioCLI if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath)) return false; var m_Shader = (Shader)item.Asset; - var str = m_Shader.Convert(Studio.Game); + var str = m_Shader.Convert(); File.WriteAllText(exportFullPath, str); return true; } diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs index 849b779..ec79c31 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.cs @@ -1045,7 +1045,7 @@ namespace AssetStudioGUI return; } - var str = ShaderConverter.Convert(m_Shader, Studio.Game); + var str = m_Shader.Convert(); PreviewText(str == null ? "Serialized Shader can't be read" : str.Replace("\n", "\r\n")); } diff --git a/AssetStudioGUI/Exporter.cs b/AssetStudioGUI/Exporter.cs index 31eeead..c3c424a 100644 --- a/AssetStudioGUI/Exporter.cs +++ b/AssetStudioGUI/Exporter.cs @@ -69,7 +69,7 @@ namespace AssetStudioGUI if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath)) return false; var m_Shader = (Shader)item.Asset; - var str = m_Shader.Convert(Studio.Game); + var str = m_Shader.Convert(); File.WriteAllText(exportFullPath, str); return true; } diff --git a/AssetStudioUtility/ShaderConverter.cs b/AssetStudioUtility/ShaderConverter.cs index 767a2d3..df46362 100644 --- a/AssetStudioUtility/ShaderConverter.cs +++ b/AssetStudioUtility/ShaderConverter.cs @@ -1,4 +1,5 @@ using K4os.Compression.LZ4; +using SpirV; using System; using System.Globalization; using System.IO; @@ -10,7 +11,7 @@ namespace AssetStudio { public static class ShaderConverter { - public static string Convert(this Shader shader, Game game) + public static string Convert(this Shader shader) { if (shader.m_SubProgramBlob != null) //5.3 - 5.4 { @@ -18,7 +19,7 @@ namespace AssetStudio LZ4Codec.Decode(shader.m_SubProgramBlob, decompressedBytes); using (var blobReader = new EndianBinaryReader(new MemoryStream(decompressedBytes), EndianType.LittleEndian)) { - var program = new ShaderProgram(blobReader, shader.version); + var program = new ShaderProgram(blobReader, shader); program.Read(blobReader, 0); return header + program.Export(Encoding.UTF8.GetString(shader.m_Script)); } @@ -26,13 +27,13 @@ namespace AssetStudio if (shader.compressedBlob != null) //5.5 and up { - return header + ConvertSerializedShader(shader, game); + return header + ConvertSerializedShader(shader); } return header + Encoding.UTF8.GetString(shader.m_Script); } - private static string ConvertSerializedShader(Shader shader, Game game) + private static string ConvertSerializedShader(Shader shader) { var length = shader.platforms.Length; var shaderPrograms = new ShaderProgram[length]; @@ -44,7 +45,7 @@ namespace AssetStudio var compressedLength = shader.compressedLengths[i][j]; var decompressedLength = shader.decompressedLengths[i][j]; var decompressedBytes = new byte[decompressedLength]; - if (game.Type.IsGISubGroup()) + if (shader.assetsFile.game.Type.IsGISubGroup()) { Buffer.BlockCopy(shader.compressedBlob, (int)offset, decompressedBytes, 0, (int)decompressedLength); } @@ -56,7 +57,7 @@ namespace AssetStudio { if (j == 0) { - shaderPrograms[i] = new ShaderProgram(blobReader, shader.version); + shaderPrograms[i] = new ShaderProgram(blobReader, shader); } shaderPrograms[i].Read(blobReader, j); } @@ -894,15 +895,21 @@ namespace AssetStudio public ShaderSubProgramEntry[] entries; public ShaderSubProgram[] m_SubPrograms; - public ShaderProgram(EndianBinaryReader reader, int[] version) + private bool hasUpdatedGpuProgram = false; + + public ShaderProgram(EndianBinaryReader reader, Shader shader) { var subProgramsCapacity = reader.ReadInt32(); entries = new ShaderSubProgramEntry[subProgramsCapacity]; for (int i = 0; i < subProgramsCapacity; i++) { - entries[i] = new ShaderSubProgramEntry(reader, version); + entries[i] = new ShaderSubProgramEntry(reader, shader.version); } m_SubPrograms = new ShaderSubProgram[subProgramsCapacity]; + if (shader.assetsFile.game.Type.IsGI()) + { + hasUpdatedGpuProgram = SerializedSubProgram.HasInstancedStructuredBuffers(shader.serializedType) || SerializedSubProgram.HasGlobalLocalKeywordIndices(shader.serializedType); + } } public void Read(EndianBinaryReader reader, int segment) @@ -913,7 +920,7 @@ namespace AssetStudio if (entry.Segment == segment) { reader.BaseStream.Position = entry.Offset; - m_SubPrograms[i] = new ShaderSubProgram(reader); + m_SubPrograms[i] = new ShaderSubProgram(reader, hasUpdatedGpuProgram); } } } @@ -938,7 +945,7 @@ namespace AssetStudio public string[] m_LocalKeywords; public byte[] m_ProgramCode; - public ShaderSubProgram(EndianBinaryReader reader) + public ShaderSubProgram(EndianBinaryReader reader, bool hasUpdatedGpuProgram) { //LoadGpuProgramFromData //201509030 - Unity 5.3 @@ -950,6 +957,10 @@ namespace AssetStudio //201806140 - Unity 2019.1~2021.1 //202012090 - Unity 2021.2 m_Version = reader.ReadInt32(); + if (hasUpdatedGpuProgram && m_Version > 201806140) + { + m_Version = 201806140; + } m_ProgramType = (ShaderGpuProgramType)reader.ReadInt32(); reader.BaseStream.Position += 12; if (m_Version >= 201608170)