Skip to content
This repository has been archived by the owner on May 11, 2024. It is now read-only.

Commit

Permalink
- [Core] Fix issue with exporting/previewing new shader foramt [GI]
Browse files Browse the repository at this point in the history
  • Loading branch information
Razmoth committed Sep 19, 2023
1 parent f8e0cc4 commit 4fcc549
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 17 deletions.
8 changes: 4 additions & 4 deletions AssetStudio/Classes/Shader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -578,8 +578,8 @@ public class SerializedSubProgram
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)
{
Expand All @@ -588,7 +588,7 @@ public SerializedSubProgram(ObjectReader reader)
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();
Expand Down Expand Up @@ -690,7 +690,7 @@ public SerializedSubProgram(ObjectReader reader)
}
}

if (HasInstancedStructuredBuffers(reader))
if (HasInstancedStructuredBuffers(reader.serializedType))
{
int numInstancedStructuredBuffers = reader.ReadInt32();
var m_InstancedStructuredBuffers = new ConstantBuffer[numInstancedStructuredBuffers];
Expand Down
2 changes: 1 addition & 1 deletion AssetStudioCLI/Exporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public static bool ExportShader(AssetItem item, string exportPath)
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;
}
Expand Down
2 changes: 1 addition & 1 deletion AssetStudioGUI/AssetStudioGUIForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,7 @@ private void PreviewShader(Shader m_Shader)
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"));
}

Expand Down
2 changes: 1 addition & 1 deletion AssetStudioGUI/Exporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public static bool ExportShader(AssetItem item, string exportPath)
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;
}
Expand Down
31 changes: 21 additions & 10 deletions AssetStudioUtility/ShaderConverter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using K4os.Compression.LZ4;
using SpirV;
using System;
using System.Globalization;
using System.IO;
Expand All @@ -10,29 +11,29 @@ 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
{
var decompressedBytes = new byte[shader.decompressedSize];
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));
}
}

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];
Expand All @@ -44,7 +45,7 @@ private static string ConvertSerializedShader(Shader shader, Game game)
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);
}
Expand All @@ -56,7 +57,7 @@ private static string ConvertSerializedShader(Shader shader, Game game)
{
if (j == 0)
{
shaderPrograms[i] = new ShaderProgram(blobReader, shader.version);
shaderPrograms[i] = new ShaderProgram(blobReader, shader);
}
shaderPrograms[i].Read(blobReader, j);
}
Expand Down Expand Up @@ -894,15 +895,21 @@ public class ShaderProgram
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)
Expand All @@ -913,7 +920,7 @@ public void Read(EndianBinaryReader reader, int segment)
if (entry.Segment == segment)
{
reader.BaseStream.Position = entry.Offset;
m_SubPrograms[i] = new ShaderSubProgram(reader);
m_SubPrograms[i] = new ShaderSubProgram(reader, hasUpdatedGpuProgram);
}
}
}
Expand All @@ -938,7 +945,7 @@ public class ShaderSubProgram
public string[] m_LocalKeywords;
public byte[] m_ProgramCode;

public ShaderSubProgram(EndianBinaryReader reader)
public ShaderSubProgram(EndianBinaryReader reader, bool hasUpdatedGpuProgram)
{
//LoadGpuProgramFromData
//201509030 - Unity 5.3
Expand All @@ -950,6 +957,10 @@ public ShaderSubProgram(EndianBinaryReader reader)
//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)
Expand Down

0 comments on commit 4fcc549

Please sign in to comment.