Add config key to dump shaders in local directory (#265)
* Add config key to dump shaders in local directory * Address feedback
This commit is contained in:
parent
063fae50fe
commit
3e13b40b35
@ -118,6 +118,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||||||
|
|
||||||
if (IsDualVp)
|
if (IsDualVp)
|
||||||
{
|
{
|
||||||
|
ShaderDumper.Dump(Memory, Position + 0x50, Type, "a");
|
||||||
|
ShaderDumper.Dump(Memory, PositionB + 0x50, Type, "b");
|
||||||
|
|
||||||
Program = Decompiler.Decompile(
|
Program = Decompiler.Decompile(
|
||||||
Memory,
|
Memory,
|
||||||
Position + 0x50,
|
Position + 0x50,
|
||||||
@ -126,6 +129,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
ShaderDumper.Dump(Memory, Position + 0x50, Type);
|
||||||
|
|
||||||
Program = Decompiler.Decompile(Memory, Position + 0x50, Type);
|
Program = Decompiler.Decompile(Memory, Position + 0x50, Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
96
Ryujinx.Graphics/Gal/ShaderDumper.cs
Normal file
96
Ryujinx.Graphics/Gal/ShaderDumper.cs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Gal
|
||||||
|
{
|
||||||
|
static class ShaderDumper
|
||||||
|
{
|
||||||
|
private static string RuntimeDir;
|
||||||
|
|
||||||
|
private static int DumpIndex = 1;
|
||||||
|
|
||||||
|
public static void Dump(IGalMemory Memory, long Position, GalShaderType Type, string ExtSuffix = "")
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(GraphicsConfig.ShadersDumpPath))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string FileName = "Shader" + DumpIndex.ToString("d4") + "." + ShaderExtension(Type) + ExtSuffix + ".bin";
|
||||||
|
|
||||||
|
string FilePath = Path.Combine(DumpDir(), FileName);
|
||||||
|
|
||||||
|
DumpIndex++;
|
||||||
|
|
||||||
|
using (FileStream Output = File.Create(FilePath))
|
||||||
|
using (BinaryWriter Writer = new BinaryWriter(Output))
|
||||||
|
{
|
||||||
|
long Offset = 0;
|
||||||
|
|
||||||
|
ulong Instruction = 0;
|
||||||
|
|
||||||
|
//Dump until a NOP instruction is found
|
||||||
|
while ((Instruction >> 52 & 0xfff8) != 0x50b0)
|
||||||
|
{
|
||||||
|
uint Word0 = (uint)Memory.ReadInt32(Position + Offset + 0);
|
||||||
|
uint Word1 = (uint)Memory.ReadInt32(Position + Offset + 4);
|
||||||
|
|
||||||
|
Instruction = Word0 | (ulong)Word1 << 32;
|
||||||
|
|
||||||
|
//Zero instructions (other kind of NOP) stop immediatly,
|
||||||
|
//this is to avoid two rows of zeroes
|
||||||
|
if (Instruction == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Writer.Write(Instruction);
|
||||||
|
|
||||||
|
Offset += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Align to meet nvdisasm requeriments
|
||||||
|
while (Offset % 0x20 != 0)
|
||||||
|
{
|
||||||
|
Writer.Write(0);
|
||||||
|
|
||||||
|
Offset += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string DumpDir()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(RuntimeDir))
|
||||||
|
{
|
||||||
|
int Index = 1;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
RuntimeDir = Path.Combine(GraphicsConfig.ShadersDumpPath, "Dumps" + Index.ToString("d2"));
|
||||||
|
|
||||||
|
Index++;
|
||||||
|
}
|
||||||
|
while (Directory.Exists(RuntimeDir));
|
||||||
|
|
||||||
|
Directory.CreateDirectory(RuntimeDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RuntimeDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ShaderExtension(GalShaderType Type)
|
||||||
|
{
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case GalShaderType.Vertex: return "vert";
|
||||||
|
case GalShaderType.TessControl: return "tesc";
|
||||||
|
case GalShaderType.TessEvaluation: return "tese";
|
||||||
|
case GalShaderType.Geometry: return "geom";
|
||||||
|
case GalShaderType.Fragment: return "frag";
|
||||||
|
|
||||||
|
default: throw new ArgumentException(nameof(Type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
Ryujinx.Graphics/GraphicsConfig.cs
Normal file
4
Ryujinx.Graphics/GraphicsConfig.cs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
public static class GraphicsConfig
|
||||||
|
{
|
||||||
|
public static string ShadersDumpPath;
|
||||||
|
}
|
@ -29,6 +29,8 @@ namespace Ryujinx
|
|||||||
|
|
||||||
AOptimizations.DisableMemoryChecks = !Convert.ToBoolean(Parser.Value("Enable_Memory_Checks"));
|
AOptimizations.DisableMemoryChecks = !Convert.ToBoolean(Parser.Value("Enable_Memory_Checks"));
|
||||||
|
|
||||||
|
GraphicsConfig.ShadersDumpPath = Parser.Value("Graphics_Shaders_Dump_Path");
|
||||||
|
|
||||||
Log.SetEnable(LogLevel.Debug, Convert.ToBoolean(Parser.Value("Logging_Enable_Debug")));
|
Log.SetEnable(LogLevel.Debug, Convert.ToBoolean(Parser.Value("Logging_Enable_Debug")));
|
||||||
Log.SetEnable(LogLevel.Stub, Convert.ToBoolean(Parser.Value("Logging_Enable_Stub")));
|
Log.SetEnable(LogLevel.Stub, Convert.ToBoolean(Parser.Value("Logging_Enable_Stub")));
|
||||||
Log.SetEnable(LogLevel.Info, Convert.ToBoolean(Parser.Value("Logging_Enable_Info")));
|
Log.SetEnable(LogLevel.Info, Convert.ToBoolean(Parser.Value("Logging_Enable_Info")));
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#Enable cpu memory checks (slow)
|
#Enable cpu memory checks (slow)
|
||||||
Enable_Memory_Checks = false
|
Enable_Memory_Checks = false
|
||||||
|
|
||||||
|
#Dump shaders in local directory (e.g. `C:\ShaderDumps`)
|
||||||
|
Graphics_Shaders_Dump_Path =
|
||||||
|
|
||||||
#Enable print debug logs
|
#Enable print debug logs
|
||||||
Logging_Enable_Debug = false
|
Logging_Enable_Debug = false
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user