aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Gpu/Shader/ShaderDumper.cs
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /src/Ryujinx.Graphics.Gpu/Shader/ShaderDumper.cs
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'src/Ryujinx.Graphics.Gpu/Shader/ShaderDumper.cs')
-rw-r--r--src/Ryujinx.Graphics.Gpu/Shader/ShaderDumper.cs129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderDumper.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderDumper.cs
new file mode 100644
index 00000000..93eeb8d7
--- /dev/null
+++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderDumper.cs
@@ -0,0 +1,129 @@
+using System.IO;
+
+namespace Ryujinx.Graphics.Gpu.Shader
+{
+ /// <summary>
+ /// Shader dumper, writes binary shader code to disk.
+ /// </summary>
+ class ShaderDumper
+ {
+ private string _runtimeDir;
+ private string _dumpPath;
+
+ /// <summary>
+ /// Current index of the shader dump binary file.
+ /// This is incremented after each save, in order to give unique names to the files.
+ /// </summary>
+ public int CurrentDumpIndex { get; private set; }
+
+ /// <summary>
+ /// Creates a new instance of the shader dumper.
+ /// </summary>
+ public ShaderDumper()
+ {
+ CurrentDumpIndex = 1;
+ }
+
+ /// <summary>
+ /// Dumps shader code to disk.
+ /// </summary>
+ /// <param name="code">Code to be dumped</param>
+ /// <param name="compute">True for compute shader code, false for graphics shader code</param>
+ /// <returns>Paths where the shader code was dumped</returns>
+ public ShaderDumpPaths Dump(byte[] code, bool compute)
+ {
+ _dumpPath = GraphicsConfig.ShadersDumpPath;
+
+ if (string.IsNullOrWhiteSpace(_dumpPath))
+ {
+ return default;
+ }
+
+ string fileName = "Shader" + CurrentDumpIndex.ToString("d4") + ".bin";
+
+ string fullPath = Path.Combine(FullDir(), fileName);
+ string codePath = Path.Combine(CodeDir(), fileName);
+
+ CurrentDumpIndex++;
+
+ using MemoryStream stream = new MemoryStream(code);
+ BinaryReader codeReader = new BinaryReader(stream);
+
+ using FileStream fullFile = File.Create(fullPath);
+ using FileStream codeFile = File.Create(codePath);
+ BinaryWriter fullWriter = new BinaryWriter(fullFile);
+ BinaryWriter codeWriter = new BinaryWriter(codeFile);
+
+ int headerSize = compute ? 0 : 0x50;
+
+ fullWriter.Write(codeReader.ReadBytes(headerSize));
+
+ byte[] temp = codeReader.ReadBytes(code.Length - headerSize);
+
+ fullWriter.Write(temp);
+ codeWriter.Write(temp);
+
+ // Align to meet nvdisasm requirements.
+ while (codeFile.Length % 0x20 != 0)
+ {
+ codeWriter.Write(0);
+ }
+
+ return new ShaderDumpPaths(fullPath, codePath);
+ }
+
+ /// <summary>
+ /// Returns the output directory for shader code with header.
+ /// </summary>
+ /// <returns>Directory path</returns>
+ private string FullDir()
+ {
+ return CreateAndReturn(Path.Combine(DumpDir(), "Full"));
+ }
+
+ /// <summary>
+ /// Returns the output directory for shader code without header.
+ /// </summary>
+ /// <returns>Directory path</returns>
+ private string CodeDir()
+ {
+ return CreateAndReturn(Path.Combine(DumpDir(), "Code"));
+ }
+
+ /// <summary>
+ /// Returns the full output directory for the current shader dump.
+ /// </summary>
+ /// <returns>Directory path</returns>
+ private string DumpDir()
+ {
+ if (string.IsNullOrEmpty(_runtimeDir))
+ {
+ int index = 1;
+
+ do
+ {
+ _runtimeDir = Path.Combine(_dumpPath, "Dumps" + index.ToString("d2"));
+
+ index++;
+ }
+ while (Directory.Exists(_runtimeDir));
+
+ Directory.CreateDirectory(_runtimeDir);
+ }
+
+ return _runtimeDir;
+ }
+
+ /// <summary>
+ /// Creates a new specified directory if needed.
+ /// </summary>
+ /// <param name="dir">The directory to create</param>
+ /// <returns>The same directory passed to the method</returns>
+ private static string CreateAndReturn(string dir)
+ {
+ Directory.CreateDirectory(dir);
+
+ return dir;
+ }
+ }
+} \ No newline at end of file