- [Core] Fix issue with exporting/previewing new shader foramt [GI]

This commit is contained in:
Razmoth
2023-09-19 15:41:22 +04:00
parent f8e0cc4de7
commit 4fcc549f99
5 changed files with 28 additions and 17 deletions

View File

@@ -578,8 +578,8 @@ namespace AssetStudio
public UAVParameter[] m_UAVParams; public UAVParameter[] m_UAVParams;
public SamplerParameter[] m_Samplers; public SamplerParameter[] m_Samplers;
private static bool HasGlobalLocalKeywordIndices(ObjectReader reader) => reader.serializedType.Match("E99740711222CD922E9A6F92FF1EB07A") || reader.serializedType.Match("450A058C218DAF000647948F2F59DA6D"); public static bool HasGlobalLocalKeywordIndices(SerializedType type) => type.Match("E99740711222CD922E9A6F92FF1EB07A") || type.Match("450A058C218DAF000647948F2F59DA6D");
private static bool HasInstancedStructuredBuffers(ObjectReader reader) => reader.serializedType.Match("E99740711222CD922E9A6F92FF1EB07A"); public static bool HasInstancedStructuredBuffers(SerializedType type) => type.Match("E99740711222CD922E9A6F92FF1EB07A");
public SerializedSubProgram(ObjectReader reader) public SerializedSubProgram(ObjectReader reader)
{ {
@@ -588,7 +588,7 @@ namespace AssetStudio
m_BlobIndex = reader.ReadUInt32(); m_BlobIndex = reader.ReadUInt32();
m_Channels = new ParserBindChannels(reader); 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(); var m_GlobalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream(); reader.AlignStream();
@@ -690,7 +690,7 @@ namespace AssetStudio
} }
} }
if (HasInstancedStructuredBuffers(reader)) if (HasInstancedStructuredBuffers(reader.serializedType))
{ {
int numInstancedStructuredBuffers = reader.ReadInt32(); int numInstancedStructuredBuffers = reader.ReadInt32();
var m_InstancedStructuredBuffers = new ConstantBuffer[numInstancedStructuredBuffers]; var m_InstancedStructuredBuffers = new ConstantBuffer[numInstancedStructuredBuffers];

View File

@@ -69,7 +69,7 @@ namespace AssetStudioCLI
if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath)) if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath))
return false; return false;
var m_Shader = (Shader)item.Asset; var m_Shader = (Shader)item.Asset;
var str = m_Shader.Convert(Studio.Game); var str = m_Shader.Convert();
File.WriteAllText(exportFullPath, str); File.WriteAllText(exportFullPath, str);
return true; return true;
} }

View File

@@ -1045,7 +1045,7 @@ namespace AssetStudioGUI
return; 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")); PreviewText(str == null ? "Serialized Shader can't be read" : str.Replace("\n", "\r\n"));
} }

View File

@@ -69,7 +69,7 @@ namespace AssetStudioGUI
if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath)) if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath))
return false; return false;
var m_Shader = (Shader)item.Asset; var m_Shader = (Shader)item.Asset;
var str = m_Shader.Convert(Studio.Game); var str = m_Shader.Convert();
File.WriteAllText(exportFullPath, str); File.WriteAllText(exportFullPath, str);
return true; return true;
} }

View File

@@ -1,4 +1,5 @@
using K4os.Compression.LZ4; using K4os.Compression.LZ4;
using SpirV;
using System; using System;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
@@ -10,7 +11,7 @@ namespace AssetStudio
{ {
public static class ShaderConverter 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 if (shader.m_SubProgramBlob != null) //5.3 - 5.4
{ {
@@ -18,7 +19,7 @@ namespace AssetStudio
LZ4Codec.Decode(shader.m_SubProgramBlob, decompressedBytes); LZ4Codec.Decode(shader.m_SubProgramBlob, decompressedBytes);
using (var blobReader = new EndianBinaryReader(new MemoryStream(decompressedBytes), EndianType.LittleEndian)) 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); program.Read(blobReader, 0);
return header + program.Export(Encoding.UTF8.GetString(shader.m_Script)); return header + program.Export(Encoding.UTF8.GetString(shader.m_Script));
} }
@@ -26,13 +27,13 @@ namespace AssetStudio
if (shader.compressedBlob != null) //5.5 and up 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); 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 length = shader.platforms.Length;
var shaderPrograms = new ShaderProgram[length]; var shaderPrograms = new ShaderProgram[length];
@@ -44,7 +45,7 @@ namespace AssetStudio
var compressedLength = shader.compressedLengths[i][j]; var compressedLength = shader.compressedLengths[i][j];
var decompressedLength = shader.decompressedLengths[i][j]; var decompressedLength = shader.decompressedLengths[i][j];
var decompressedBytes = new byte[decompressedLength]; 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); Buffer.BlockCopy(shader.compressedBlob, (int)offset, decompressedBytes, 0, (int)decompressedLength);
} }
@@ -56,7 +57,7 @@ namespace AssetStudio
{ {
if (j == 0) if (j == 0)
{ {
shaderPrograms[i] = new ShaderProgram(blobReader, shader.version); shaderPrograms[i] = new ShaderProgram(blobReader, shader);
} }
shaderPrograms[i].Read(blobReader, j); shaderPrograms[i].Read(blobReader, j);
} }
@@ -894,15 +895,21 @@ namespace AssetStudio
public ShaderSubProgramEntry[] entries; public ShaderSubProgramEntry[] entries;
public ShaderSubProgram[] m_SubPrograms; public ShaderSubProgram[] m_SubPrograms;
public ShaderProgram(EndianBinaryReader reader, int[] version) private bool hasUpdatedGpuProgram = false;
public ShaderProgram(EndianBinaryReader reader, Shader shader)
{ {
var subProgramsCapacity = reader.ReadInt32(); var subProgramsCapacity = reader.ReadInt32();
entries = new ShaderSubProgramEntry[subProgramsCapacity]; entries = new ShaderSubProgramEntry[subProgramsCapacity];
for (int i = 0; i < subProgramsCapacity; i++) 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]; 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) public void Read(EndianBinaryReader reader, int segment)
@@ -913,7 +920,7 @@ namespace AssetStudio
if (entry.Segment == segment) if (entry.Segment == segment)
{ {
reader.BaseStream.Position = entry.Offset; 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 string[] m_LocalKeywords;
public byte[] m_ProgramCode; public byte[] m_ProgramCode;
public ShaderSubProgram(EndianBinaryReader reader) public ShaderSubProgram(EndianBinaryReader reader, bool hasUpdatedGpuProgram)
{ {
//LoadGpuProgramFromData //LoadGpuProgramFromData
//201509030 - Unity 5.3 //201509030 - Unity 5.3
@@ -950,6 +957,10 @@ namespace AssetStudio
//201806140 - Unity 2019.1~2021.1 //201806140 - Unity 2019.1~2021.1
//202012090 - Unity 2021.2 //202012090 - Unity 2021.2
m_Version = reader.ReadInt32(); m_Version = reader.ReadInt32();
if (hasUpdatedGpuProgram && m_Version > 201806140)
{
m_Version = 201806140;
}
m_ProgramType = (ShaderGpuProgramType)reader.ReadInt32(); m_ProgramType = (ShaderGpuProgramType)reader.ReadInt32();
reader.BaseStream.Position += 12; reader.BaseStream.Position += 12;
if (m_Version >= 201608170) if (m_Version >= 201608170)