public void RecompileTest(string relPath) { // Arrange. var file = $"{ShaderDirectory}/{relPath}"; var relDir = Path.GetDirectoryName(relPath); Directory.CreateDirectory($"{OutputDir}/{relDir}"); var sourceName = GetSourceNameFromObject($"{ShaderDirectory}/{relPath}.o"); if (ShaderDirectory != OutputDir) { File.Copy($"{ShaderDirectory}/{relDir}/{sourceName}", $"{OutputDir}/{relDir}/{sourceName}", true); } if (ShaderDirectory != OutputDir) { File.Copy($"{ShaderDirectory}/{relPath}.asm", $"{OutputDir}/{relPath}.asm", true); } var asmFileText = string.Join(Environment.NewLine, File.ReadAllLines(file + ".asm").Select(x => x.Trim())); // Act. var binaryFileBytes = File.ReadAllBytes(file + ".o"); using (var shaderBytecode = ShaderBytecode.FromStream(new MemoryStream(binaryFileBytes))) { var shaderVersion = shaderBytecode.GetVersion(); var shaderCode = DXDecompiler.Decompile(File.ReadAllBytes(file + ".o")); File.WriteAllText($"{OutputDir}/{relPath}.d.hlsl", shaderCode); var entryPoint = TestUtils.GetShaderEntryPoint(shaderVersion); var profile = TestUtils.GetShaderProfile(shaderVersion); var compiledShader = ShaderBytecode.Compile(shaderCode, entryPoint, profile); var disassembly = shaderBytecode.Disassemble(); var redisassembly = compiledShader.Bytecode.Disassemble(); File.WriteAllText($"{OutputDir}/{relPath}.d1.asm", disassembly); File.WriteAllText($"{OutputDir}/{relPath}.d2.asm", redisassembly); // Assert. Warn.If(disassembly, Is.EqualTo(redisassembly)); //Assert.Warn("Dissassembly does not match"); } }
public void DecompileShaders(string relPath) { // Arrange. var file = $"{ShaderDirectory}/{relPath}"; var relDir = Path.GetDirectoryName(relPath); Directory.CreateDirectory($"{OutputDir}/{relDir}"); var sourceName = GetSourceNameFromObject($"{ShaderDirectory}/{relPath}.o"); if (ShaderDirectory != OutputDir) { File.Copy($"{ShaderDirectory}/{relDir}/{sourceName}", $"{OutputDir}/{relDir}/{sourceName}", true); } // Act. var shaderCode = DXDecompiler.Decompile(File.ReadAllBytes(file + ".o")); File.WriteAllText($"{OutputDir}/{relPath}.d.hlsl", shaderCode); // Assert. }
static void Main(string[] args) { args = new string[] { "-O", "test.html", "-h", @"C:\Files\KM\ShaderStudio\src\UnityTests\bin\Debug\Blob\outer_wilds\Assets\Shader\SpritesDefault\VS_BF58DDF502C51FEB5145F1D0310B4327.o" }; var options = new Options(); for (int i = 0; i < args.Length; i++) { switch (args[i]) { case "-O": if (args.Length <= i + 1) { Console.Error.WriteLine("No output path specified"); return; } options.DestPath = args[i + 1]; i += 1; break; case "-a": options.Mode = DecompileMode.Dissassemble; break; case "-d": options.Mode = DecompileMode.Debug; break; case "-h": options.Mode = DecompileMode.DebugHtml; break; default: options.SourcePath = args[i]; break; } } if (string.IsNullOrEmpty(options.SourcePath)) { Console.Error.WriteLine("No source path specified"); Environment.Exit(1); } byte[] data = null; try { data = File.ReadAllBytes(options.SourcePath); } catch (Exception ex) { Console.Error.WriteLine("Error reading source"); Console.Error.WriteLine(ex); Environment.Exit(1); } var programType = GetProgramType(data); using (var sw = GetStream(options)) { if (programType == ProgramType.Unknown) { Console.Error.WriteLine($"Unable to identify shader object format"); Environment.Exit(1); } else if (programType == ProgramType.DXBC) { if (options.Mode == DecompileMode.Dissassemble) { var container = new BytecodeContainer(data); sw.Write(container.ToString()); } else if (options.Mode == DecompileMode.Decompile) { var hlsl = DXDecompiler.Decompile(data); sw.Write(hlsl); } else if (options.Mode == DecompileMode.Debug) { sw.WriteLine(string.Join(" ", args)); var shaderBytecode = DebugBytecodeContainer.Parse(data); var result = shaderBytecode.Dump(); sw.Write(result); } else if (options.Mode == DecompileMode.DebugHtml) { var shaderBytecode = DebugBytecodeContainer.Parse(data); var result = shaderBytecode.DumpHTML(); sw.Write(result); } } else if (programType == ProgramType.DX9) { if (options.Mode == DecompileMode.Dissassemble) { var disasm = SlimShader.DX9Shader.AsmWriter.Disassemble(data); sw.Write(disasm); } else if (options.Mode == DecompileMode.Decompile) { var hlsl = SlimShader.DX9Shader.HlslWriter.Decompile(data); sw.Write(hlsl); } else if (options.Mode == DecompileMode.Debug) { sw.WriteLine(string.Join(" ", args)); var shaderType = (SlimShader.DX9Shader.ShaderType)BitConverter.ToUInt16(data, 2); if (shaderType == SlimShader.DX9Shader.ShaderType.Effect) { var reader = new DebugBytecodeReader(data, 0, data.Length); string error = ""; try { reader.ReadByte("minorVersion"); reader.ReadByte("majorVersion"); reader.ReadUInt16("shaderType"); DebugEffectChunk.Parse(reader, (uint)(data.Length - 4)); } catch (Exception ex) { error = ex.ToString(); } var dump = reader.DumpStructure(); if (!string.IsNullOrEmpty(error)) { dump += "\n" + error; } sw.Write(dump); } else { var reader = new DebugBytecodeReader(data, 0, data.Length); string error = ""; try { DebugShaderModel.Parse(reader); } catch (Exception ex) { error = ex.ToString(); } var dump = reader.DumpStructure(); if (!string.IsNullOrEmpty(error)) { dump += "\n" + error; } sw.Write(dump); } } else if (options.Mode == DecompileMode.DebugHtml) { var shaderType = (SlimShader.DX9Shader.ShaderType)BitConverter.ToUInt16(data, 2); if (shaderType == SlimShader.DX9Shader.ShaderType.Effect) { var reader = new DebugBytecodeReader(data, 0, data.Length); string error = ""; try { reader.ReadByte("minorVersion"); reader.ReadByte("majorVersion"); reader.ReadUInt16("shaderType"); DebugEffectChunk.Parse(reader, (uint)(data.Length - 4)); } catch (Exception ex) { error = ex.ToString(); } var dump = reader.DumpHtml(); if (!string.IsNullOrEmpty(error)) { dump += "\n" + error; } sw.Write(dump); } else { var reader = new DebugBytecodeReader(data, 0, data.Length); string error = ""; try { DebugShaderModel.Parse(reader); } catch (Exception ex) { error = ex.ToString(); } var dump = reader.DumpHtml(); if (!string.IsNullOrEmpty(error)) { dump += "\n" + error; } sw.Write(dump); } } } } }
static void Main(string[] args) { var options = new Options(); for (int i = 0; i < args.Length; i++) { switch (args[i]) { case "-O": if (args.Length <= i + 1) { Console.Error.WriteLine("No output path specified"); return; } options.DestPath = args[i + 1]; i += 1; break; case "-d": options.Mode = DecompileMode.Dissassemble; break; default: options.SourcePath = args[i]; break; } } if (string.IsNullOrEmpty(options.SourcePath)) { Console.Error.WriteLine("No source path specified"); Environment.Exit(1); } byte[] data = null; try { data = File.ReadAllBytes(options.SourcePath); } catch (Exception ex) { Console.Error.WriteLine("Error reading source"); Console.Error.WriteLine(ex); Environment.Exit(1); } var programType = GetProgramType(data); using (var sw = GetStream(options)) { if (programType == ProgramType.Unknown) { Console.Error.WriteLine($"Unable to identify shader object format"); Environment.Exit(1); } else if (programType == ProgramType.DXBC) { if (options.Mode == DecompileMode.Dissassemble) { var container = new BytecodeContainer(data); sw.Write(container.ToString()); } else { var hlsl = DXDecompiler.Decompile(data); sw.Write(hlsl); } } else if (programType == ProgramType.DX9) { if (options.Mode == DecompileMode.Dissassemble) { var disasm = SlimShader.DX9Shader.AsmWriter.Disassemble(data); sw.Write(disasm); } else { var hlsl = SlimShader.DX9Shader.HlslWriter.Decompile(data); sw.Write(hlsl); } } } }