Fixed bug

This commit is contained in:
Perfare 2018-12-11 23:36:15 +08:00
parent d156b5d947
commit f8ffaa0400
2 changed files with 147 additions and 49 deletions

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
namespace AssetStudio namespace AssetStudio
{ {
@ -188,7 +189,7 @@ namespace AssetStudio
kFogDisabled = 0, kFogDisabled = 0,
kFogLinear = 1, kFogLinear = 1,
kFogExp = 2, kFogExp = 2,
kFogExp2 = 3, kFogExp2 = 3
}; };
public class SerializedShaderState public class SerializedShaderState
@ -446,7 +447,7 @@ namespace AssetStudio
kShaderGpuProgramMetalVS = 23, kShaderGpuProgramMetalVS = 23,
kShaderGpuProgramMetalFS = 24, kShaderGpuProgramMetalFS = 24,
kShaderGpuProgramSPIRV = 25, kShaderGpuProgramSPIRV = 25,
kShaderGpuProgramConsole = 26, kShaderGpuProgramConsole = 26
}; };
public class SerializedSubProgram public class SerializedSubProgram
@ -701,6 +702,32 @@ namespace AssetStudio
} }
} }
public enum ShaderCompilerPlatform
{
kShaderCompPlatformNone = -1,
kShaderCompPlatformGL = 0,
kShaderCompPlatformD3D9 = 1,
kShaderCompPlatformXbox360 = 2,
kShaderCompPlatformPS3 = 3,
kShaderCompPlatformD3D11 = 4,
kShaderCompPlatformGLES20 = 5,
kShaderCompPlatformNaCl = 6,
kShaderCompPlatformFlash = 7,
kShaderCompPlatformD3D11_9x = 8,
kShaderCompPlatformGLES3Plus = 9,
kShaderCompPlatformPSP2 = 10,
kShaderCompPlatformPS4 = 11,
kShaderCompPlatformXboxOne = 12,
kShaderCompPlatformPSM = 13,
kShaderCompPlatformMetal = 14,
kShaderCompPlatformOpenGLCore = 15,
kShaderCompPlatformN3DS = 16,
kShaderCompPlatformWiiU = 17,
kShaderCompPlatformVulkan = 18,
kShaderCompPlatformSwitch = 19,
kShaderCompPlatformXboxOneD3D12 = 20
};
public class Shader : NamedObject public class Shader : NamedObject
{ {
public byte[] m_Script; public byte[] m_Script;
@ -709,7 +736,7 @@ namespace AssetStudio
public byte[] m_SubProgramBlob; public byte[] m_SubProgramBlob;
//5.5 and up //5.5 and up
public SerializedShader m_ParsedForm; public SerializedShader m_ParsedForm;
public uint[] platforms; public ShaderCompilerPlatform[] platforms;
public uint[] offsets; public uint[] offsets;
public uint[] compressedLengths; public uint[] compressedLengths;
public uint[] decompressedLengths; public uint[] decompressedLengths;
@ -720,7 +747,7 @@ namespace AssetStudio
if (version[0] == 5 && version[1] >= 5 || version[0] > 5) //5.5 and up if (version[0] == 5 && version[1] >= 5 || version[0] > 5) //5.5 and up
{ {
m_ParsedForm = new SerializedShader(reader); m_ParsedForm = new SerializedShader(reader);
platforms = reader.ReadUInt32Array(); platforms = reader.ReadUInt32Array().Select(x => (ShaderCompilerPlatform)x).ToArray();
offsets = reader.ReadUInt32Array(); offsets = reader.ReadUInt32Array();
compressedLengths = reader.ReadUInt32Array(); compressedLengths = reader.ReadUInt32Array();
decompressedLengths = reader.ReadUInt32Array(); decompressedLengths = reader.ReadUInt32Array();

View File

@ -51,7 +51,7 @@ namespace AssetStudio
using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes))) using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
{ {
var program = new ShaderProgram(blobReader); var program = new ShaderProgram(blobReader);
var m_Script = ConvertSerializedShader(shader.m_ParsedForm, shader.platforms[i], i); var m_Script = ConvertSerializedShader(shader.m_ParsedForm, shader.platforms[i]);
strs[i] = program.Export(m_Script); strs[i] = program.Export(m_Script);
} }
} }
@ -62,7 +62,7 @@ namespace AssetStudio
return null; return null;
} }
private static string ConvertSerializedShader(SerializedShader m_ParsedForm, uint platform, int platformIndex) private static string ConvertSerializedShader(SerializedShader m_ParsedForm, ShaderCompilerPlatform platform)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.Append($"Shader \"{m_ParsedForm.m_Name}\" {{\n"); sb.Append($"Shader \"{m_ParsedForm.m_Name}\" {{\n");
@ -71,7 +71,7 @@ namespace AssetStudio
foreach (var m_SubShader in m_ParsedForm.m_SubShaders) foreach (var m_SubShader in m_ParsedForm.m_SubShaders)
{ {
sb.Append(ConvertSerializedSubShader(m_SubShader, platform, platformIndex)); sb.Append(ConvertSerializedSubShader(m_SubShader, platform));
} }
if (!string.IsNullOrEmpty(m_ParsedForm.m_FallbackName)) if (!string.IsNullOrEmpty(m_ParsedForm.m_FallbackName))
@ -88,7 +88,7 @@ namespace AssetStudio
return sb.ToString(); return sb.ToString();
} }
private static string ConvertSerializedSubShader(SerializedSubShader m_SubShader, uint platform, int platformIndex) private static string ConvertSerializedSubShader(SerializedSubShader m_SubShader, ShaderCompilerPlatform platform)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.Append("SubShader {\n"); sb.Append("SubShader {\n");
@ -101,13 +101,13 @@ namespace AssetStudio
foreach (var m_Passe in m_SubShader.m_Passes) foreach (var m_Passe in m_SubShader.m_Passes)
{ {
sb.Append(ConvertSerializedPass(m_Passe, platform, platformIndex)); sb.Append(ConvertSerializedPass(m_Passe, platform));
} }
sb.Append("}\n"); sb.Append("}\n");
return sb.ToString(); return sb.ToString();
} }
private static string ConvertSerializedPass(SerializedPass m_Passe, uint platform, int platformIndex) private static string ConvertSerializedPass(SerializedPass m_Passe, ShaderCompilerPlatform platform)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
switch (m_Passe.m_Type) switch (m_Passe.m_Type)
@ -144,35 +144,35 @@ namespace AssetStudio
if (m_Passe.progVertex.m_SubPrograms.Length > 0) if (m_Passe.progVertex.m_SubPrograms.Length > 0)
{ {
sb.Append("Program \"vp\" {\n"); sb.Append("Program \"vp\" {\n");
sb.Append(ConvertSerializedSubPrograms(m_Passe.progVertex.m_SubPrograms, platform, platformIndex)); sb.Append(ConvertSerializedSubPrograms(m_Passe.progVertex.m_SubPrograms, platform));
sb.Append("}\n"); sb.Append("}\n");
} }
if (m_Passe.progFragment.m_SubPrograms.Length > 0) if (m_Passe.progFragment.m_SubPrograms.Length > 0)
{ {
sb.Append("Program \"fp\" {\n"); sb.Append("Program \"fp\" {\n");
sb.Append(ConvertSerializedSubPrograms(m_Passe.progFragment.m_SubPrograms, platform, platformIndex)); sb.Append(ConvertSerializedSubPrograms(m_Passe.progFragment.m_SubPrograms, platform));
sb.Append("}\n"); sb.Append("}\n");
} }
if (m_Passe.progGeometry.m_SubPrograms.Length > 0) if (m_Passe.progGeometry.m_SubPrograms.Length > 0)
{ {
sb.Append("Program \"gp\" {\n"); sb.Append("Program \"gp\" {\n");
sb.Append(ConvertSerializedSubPrograms(m_Passe.progGeometry.m_SubPrograms, platform, platformIndex)); sb.Append(ConvertSerializedSubPrograms(m_Passe.progGeometry.m_SubPrograms, platform));
sb.Append("}\n"); sb.Append("}\n");
} }
if (m_Passe.progHull.m_SubPrograms.Length > 0) if (m_Passe.progHull.m_SubPrograms.Length > 0)
{ {
sb.Append("Program \"hp\" {\n"); sb.Append("Program \"hp\" {\n");
sb.Append(ConvertSerializedSubPrograms(m_Passe.progHull.m_SubPrograms, platform, platformIndex)); sb.Append(ConvertSerializedSubPrograms(m_Passe.progHull.m_SubPrograms, platform));
sb.Append("}\n"); sb.Append("}\n");
} }
if (m_Passe.progDomain.m_SubPrograms.Length > 0) if (m_Passe.progDomain.m_SubPrograms.Length > 0)
{ {
sb.Append("Program \"dp\" {\n"); sb.Append("Program \"dp\" {\n");
sb.Append(ConvertSerializedSubPrograms(m_Passe.progDomain.m_SubPrograms, platform, platformIndex)); sb.Append(ConvertSerializedSubPrograms(m_Passe.progDomain.m_SubPrograms, platform));
sb.Append("}\n"); sb.Append("}\n");
} }
} }
@ -181,27 +181,31 @@ namespace AssetStudio
return sb.ToString(); return sb.ToString();
} }
private static string ConvertSerializedSubPrograms(SerializedSubProgram[] m_SubPrograms, uint platform, int platformIndex) private static string ConvertSerializedSubPrograms(SerializedSubProgram[] m_SubPrograms, ShaderCompilerPlatform platform)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
var groups = m_SubPrograms.GroupBy(x => x.m_BlobIndex); var groups = m_SubPrograms.GroupBy(x => x.m_BlobIndex);
foreach (var group in groups) foreach (var group in groups)
{ {
var programs = group.GroupBy(x => x.m_GpuProgramType).ToList(); var programs = group.GroupBy(x => x.m_GpuProgramType);
if (platformIndex < programs.Count) foreach (var program in programs)
{ {
var subPrograms = programs[platformIndex].ToList(); if (CheckGpuProgramUsable(platform, program.Key))
var isTier = subPrograms.Count > 1;
foreach (var subProgram in subPrograms)
{ {
sb.Append($"SubProgram \"{GetPlatformString(platform)} "); var subPrograms = program.ToList();
if (isTier) var isTier = subPrograms.Count > 1;
foreach (var subProgram in subPrograms)
{ {
sb.Append($"hw_tier{subProgram.m_ShaderHardwareTier:00} "); sb.Append($"SubProgram \"{GetPlatformString(platform)} ");
if (isTier)
{
sb.Append($"hw_tier{subProgram.m_ShaderHardwareTier:00} ");
}
sb.Append("\" {\n");
sb.Append($"GpuProgramIndex {subProgram.m_BlobIndex}\n");
sb.Append("}\n");
} }
sb.Append("\" {\n"); break;
sb.Append($"GpuProgramIndex {subProgram.m_BlobIndex}\n");
sb.Append("}\n");
} }
} }
} }
@ -424,51 +428,118 @@ namespace AssetStudio
return sb.ToString(); return sb.ToString();
} }
public static string GetPlatformString(uint platform) private static bool CheckGpuProgramUsable(ShaderCompilerPlatform platform, ShaderGpuProgramType programType)
{ {
switch (platform) switch (platform)
{ {
case 0: //kShaderCompPlatformGL case ShaderCompilerPlatform.kShaderCompPlatformGL:
return programType == ShaderGpuProgramType.kShaderGpuProgramGLLegacy;
case ShaderCompilerPlatform.kShaderCompPlatformD3D9:
return programType == ShaderGpuProgramType.kShaderGpuProgramDX9VertexSM20
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX9VertexSM30
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX9PixelSM20
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX9PixelSM30;
case ShaderCompilerPlatform.kShaderCompPlatformXbox360:
throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformPS3:
throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformD3D11:
return programType == ShaderGpuProgramType.kShaderGpuProgramDX11VertexSM40
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11VertexSM50
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11PixelSM40
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11PixelSM50
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11GeometrySM40
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11GeometrySM50
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11HullSM50
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11DomainSM50;
case ShaderCompilerPlatform.kShaderCompPlatformGLES20:
return programType == ShaderGpuProgramType.kShaderGpuProgramGLES;
case ShaderCompilerPlatform.kShaderCompPlatformNaCl:
throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformFlash:
throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformD3D11_9x:
return programType == ShaderGpuProgramType.kShaderGpuProgramDX10Level9Vertex
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX10Level9Pixel;
case ShaderCompilerPlatform.kShaderCompPlatformGLES3Plus:
return programType == ShaderGpuProgramType.kShaderGpuProgramGLES31AEP
|| programType == ShaderGpuProgramType.kShaderGpuProgramGLES31
|| programType == ShaderGpuProgramType.kShaderGpuProgramGLES3;
case ShaderCompilerPlatform.kShaderCompPlatformPSP2:
throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformPS4:
throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformXboxOne:
throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformPSM:
throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformMetal:
return programType == ShaderGpuProgramType.kShaderGpuProgramMetalVS
|| programType == ShaderGpuProgramType.kShaderGpuProgramMetalFS;
case ShaderCompilerPlatform.kShaderCompPlatformOpenGLCore:
return programType == ShaderGpuProgramType.kShaderGpuProgramGLCore32
|| programType == ShaderGpuProgramType.kShaderGpuProgramGLCore41
|| programType == ShaderGpuProgramType.kShaderGpuProgramGLCore43;
case ShaderCompilerPlatform.kShaderCompPlatformN3DS:
throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformWiiU:
throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformVulkan:
return programType == ShaderGpuProgramType.kShaderGpuProgramSPIRV;
case ShaderCompilerPlatform.kShaderCompPlatformSwitch:
throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformXboxOneD3D12:
throw new NotSupportedException();
default:
throw new NotSupportedException();
}
}
public static string GetPlatformString(ShaderCompilerPlatform platform)
{
switch (platform)
{
case ShaderCompilerPlatform.kShaderCompPlatformGL:
return "openGL"; return "openGL";
case 1: //kShaderCompPlatformD3D9 case ShaderCompilerPlatform.kShaderCompPlatformD3D9:
return "d3d9"; return "d3d9";
case 2: //kShaderCompPlatformXbox360 case ShaderCompilerPlatform.kShaderCompPlatformXbox360:
return "xbox360"; return "xbox360";
case 3: //kShaderCompPlatformPS3 case ShaderCompilerPlatform.kShaderCompPlatformPS3:
return "ps3"; return "ps3";
case 4: //kShaderCompPlatformD3D11 case ShaderCompilerPlatform.kShaderCompPlatformD3D11:
return "d3d11"; return "d3d11";
case 5: //kShaderCompPlatformGLES20 case ShaderCompilerPlatform.kShaderCompPlatformGLES20:
return "gles"; return "gles";
case 6: //kShaderCompPlatformNaCl case ShaderCompilerPlatform.kShaderCompPlatformNaCl:
return "glesdesktop"; return "glesdesktop";
case 7: //kShaderCompPlatformFlash case ShaderCompilerPlatform.kShaderCompPlatformFlash:
return "flash"; return "flash";
case 8: //kShaderCompPlatformD3D11_9x case ShaderCompilerPlatform.kShaderCompPlatformD3D11_9x:
return "d3d11_9x"; return "d3d11_9x";
case 9: //kShaderCompPlatformGLES3Plus case ShaderCompilerPlatform.kShaderCompPlatformGLES3Plus:
return "gles3"; return "gles3";
case 10: //kShaderCompPlatformPSP2 case ShaderCompilerPlatform.kShaderCompPlatformPSP2:
return "psp2"; return "psp2";
case 11: //kShaderCompPlatformPS4 case ShaderCompilerPlatform.kShaderCompPlatformPS4:
return "ps4"; return "ps4";
case 12: //kShaderCompPlatformXboxOne case ShaderCompilerPlatform.kShaderCompPlatformXboxOne:
return "xboxone"; return "xboxone";
case 13: //kShaderCompPlatformPSM case ShaderCompilerPlatform.kShaderCompPlatformPSM:
return "psm"; return "psm";
case 14: //kShaderCompPlatformMetal case ShaderCompilerPlatform.kShaderCompPlatformMetal:
return "metal"; return "metal";
case 15: //kShaderCompPlatformOpenGLCore case ShaderCompilerPlatform.kShaderCompPlatformOpenGLCore:
return "glcore"; return "glcore";
case 16: //kShaderCompPlatformN3DS case ShaderCompilerPlatform.kShaderCompPlatformN3DS:
return "n3ds"; return "n3ds";
case 17: //kShaderCompPlatformWiiU case ShaderCompilerPlatform.kShaderCompPlatformWiiU:
return "wiiu"; return "wiiu";
case 18: //kShaderCompPlatformVulkan case ShaderCompilerPlatform.kShaderCompPlatformVulkan:
return "vulkan"; return "vulkan";
case 19: //kShaderCompPlatformSwitch case ShaderCompilerPlatform.kShaderCompPlatformSwitch:
return "switch"; return "switch";
case 20: //kShaderCompPlatformXboxOneD3D12 case ShaderCompilerPlatform.kShaderCompPlatformXboxOneD3D12:
return "xboxone_d3d12"; return "xboxone_d3d12";
default: default:
return "unknown"; return "unknown";