public static DebugPreshader Parse(DebugBytecodeReader reader) { var result = new DebugPreshader(); result.Shader = DebugShaderModel.Parse(reader); return(result); }
public static DebugStateBlob Parse(DebugBytecodeReader reader, DebugBytecodeReader blobReader) { var result = new DebugStateBlob(); result.TechniqueIndex = blobReader.ReadUInt32("TechniqueIndex"); result.PassIndex = blobReader.ReadUInt32("PassIndex"); result.SamplerStateIndex = blobReader.ReadUInt32("SamplerStateIndex"); result.AssignmentIndex = blobReader.ReadUInt32("AssignmentIndex"); result.BlobType = blobReader.ReadEnum32 <StateBlobType>("BlobType"); if (result.BlobType == StateBlobType.Shader) { result.ShaderSize = blobReader.ReadUInt32("BlobSize"); var startPosition = blobReader._reader.BaseStream.Position; var shaderReader = blobReader.CopyAtCurrentPosition("ShaderReader", blobReader); result.Shader = DebugShaderModel.Parse(shaderReader); blobReader._reader.BaseStream.Position = startPosition + result.ShaderSize; } if (result.BlobType == StateBlobType.Variable) { result.VariableName = blobReader.TryReadString("VariableName"); } else if (result.BlobType == StateBlobType.IndexShader) { result.ShaderSize = blobReader.ReadUInt32("BlobSize"); var startPosition = blobReader._reader.BaseStream.Position; var variableSize = blobReader.ReadUInt32("VariableNameSize"); var variableData = blobReader.ReadBytes("VariableData", (int)variableSize); result.VariableName = Encoding.UTF8.GetString(variableData, 0, variableData.Length - 1); var shaderReader = blobReader.CopyAtCurrentPosition("ShaderReader", blobReader); result.Shader = DebugShaderModel.Parse(shaderReader); blobReader._reader.BaseStream.Position = startPosition + result.ShaderSize; } return(result); }
public void DumpStructure(string relPath) { string file = $"{ShaderDirectory}/{relPath}"; // Arrange. // Act. var bytecode = File.ReadAllBytes(file + ".o"); var reader = new DebugParser.DebugBytecodeReader(bytecode, 0, bytecode.Length); string error = ""; try { if (bytecode[2] == 255 && bytecode[3] == 254) { reader.ReadByte("minorVersion"); reader.ReadByte("majorVersion"); reader.ReadUInt16("shaderType"); DebugEffectChunk.Parse(reader, (uint)(bytecode.Length - 4)); } else { var shaderModel = DebugShaderModel.Parse(reader); } } catch (Exception ex) { error = ex.ToString(); } var dump = reader.DumpStructure(); if (!string.IsNullOrEmpty(error)) { dump += "\n" + error; } File.WriteAllText($"{file}.d.txt", dump); var dumpHtml = ""; try { dumpHtml = reader.DumpHtml(); } catch (Exception ex) { } File.WriteAllText($"{file}.d.html", dumpHtml); if (!string.IsNullOrEmpty(error)) { Assert.That(false, error); } //Assert.That(!dump.Contains("Unread Memory"), "Unread memory found"); // Assert. }
public static DebugBinaryData Parse(DebugBytecodeReader reader, DebugBytecodeReader blobReader) { var result = new DebugBinaryData(); result.Index = blobReader.ReadUInt32("Index"); result.Size = blobReader.ReadUInt32("Size"); var startPosition = blobReader._reader.BaseStream.Position; var header = blobReader.PeakUint32(); var shaderType = (ShaderType)(header >> 16); var paddedSize = result.Size + (result.Size % 4 == 0 ? 0 : 4 - result.Size % 4); if (shaderType == ShaderType.Pixel || shaderType == ShaderType.Vertex || shaderType == ShaderType.Expression) { var shaderReader = blobReader.CopyAtCurrentPosition("ShaderReader", blobReader); result.Shader = DebugShaderModel.Parse(shaderReader); } else if (result.Size > 0) { blobReader.ReadBytes("Value", (int)paddedSize); } blobReader._reader.BaseStream.Position = startPosition + paddedSize; return(result); }
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); } } } } }