ShaderDumper.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. using Ryujinx.Graphics.Shader.Translation;
  2. using System;
  3. using System.IO;
  4. namespace Ryujinx.Graphics.Gpu.Engine
  5. {
  6. class ShaderDumper
  7. {
  8. private GpuContext _context;
  9. private string _runtimeDir;
  10. private string _dumpPath;
  11. private int _dumpIndex;
  12. public int CurrentDumpIndex => _dumpIndex;
  13. public ShaderDumper(GpuContext context)
  14. {
  15. _context = context;
  16. _dumpIndex = 1;
  17. }
  18. public void Dump(Span<byte> code, bool compute, out string fullPath, out string codePath)
  19. {
  20. _dumpPath = GraphicsConfig.ShadersDumpPath;
  21. if (string.IsNullOrWhiteSpace(_dumpPath))
  22. {
  23. fullPath = null;
  24. codePath = null;
  25. return;
  26. }
  27. string fileName = "Shader" + _dumpIndex.ToString("d4") + ".bin";
  28. fullPath = Path.Combine(FullDir(), fileName);
  29. codePath = Path.Combine(CodeDir(), fileName);
  30. _dumpIndex++;
  31. code = Translator.ExtractCode(code, compute, out int headerSize);
  32. using (MemoryStream stream = new MemoryStream(code.ToArray()))
  33. {
  34. BinaryReader codeReader = new BinaryReader(stream);
  35. using (FileStream fullFile = File.Create(fullPath))
  36. using (FileStream codeFile = File.Create(codePath))
  37. {
  38. BinaryWriter fullWriter = new BinaryWriter(fullFile);
  39. BinaryWriter codeWriter = new BinaryWriter(codeFile);
  40. fullWriter.Write(codeReader.ReadBytes(headerSize));
  41. byte[] temp = codeReader.ReadBytes(code.Length - headerSize);
  42. fullWriter.Write(temp);
  43. codeWriter.Write(temp);
  44. // Align to meet nvdisasm requirements.
  45. while (codeFile.Length % 0x20 != 0)
  46. {
  47. codeWriter.Write(0);
  48. }
  49. }
  50. }
  51. }
  52. private string FullDir()
  53. {
  54. return CreateAndReturn(Path.Combine(DumpDir(), "Full"));
  55. }
  56. private string CodeDir()
  57. {
  58. return CreateAndReturn(Path.Combine(DumpDir(), "Code"));
  59. }
  60. private string DumpDir()
  61. {
  62. if (string.IsNullOrEmpty(_runtimeDir))
  63. {
  64. int index = 1;
  65. do
  66. {
  67. _runtimeDir = Path.Combine(_dumpPath, "Dumps" + index.ToString("d2"));
  68. index++;
  69. }
  70. while (Directory.Exists(_runtimeDir));
  71. Directory.CreateDirectory(_runtimeDir);
  72. }
  73. return _runtimeDir;
  74. }
  75. private static string CreateAndReturn(string dir)
  76. {
  77. Directory.CreateDirectory(dir);
  78. return dir;
  79. }
  80. }
  81. }