Add config key to dump shaders in local directory

This commit is contained in:
ReinUsesLisp 2018-07-14 01:34:04 -03:00
parent 514218ab98
commit 561fab56ac
5 changed files with 108 additions and 0 deletions

View file

@ -0,0 +1,4 @@
public static class AGraphicsConfig
{
public static string ShadersDumpPath = "";
}

View file

@ -118,6 +118,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
if (IsDualVp)
{
ShaderDumper.Dump(Memory, Position + 0x50, Type, "a");
ShaderDumper.Dump(Memory, PositionB + 0x50, Type, "b");
Program = Decompiler.Decompile(
Memory,
Position + 0x50,
@ -126,6 +129,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
else
{
ShaderDumper.Dump(Memory, Position + 0x50, Type);
Program = Decompiler.Decompile(Memory, Position + 0x50, Type);
}

View file

@ -0,0 +1,94 @@
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 (AGraphicsConfig.ShadersDumpPath == "")
{
return;
}
string Path = DumpDir() + "/Shader" + DumpIndex.ToString("d4") + "." + ShaderExtension(Type) + ExtSuffix + ".bin";
DumpIndex++;
using (FileStream Output = File.Create(Path))
using (BinaryWriter Writer = new BinaryWriter(Output))
{
long Offset = 0;
ulong Instruction = 0;
//Dump until a NOP instruction is found
while (Instruction >> 52 != 0x50b)
{
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 (RuntimeDir == "")
{
int Index = 1;
do
{
RuntimeDir = AGraphicsConfig.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));
}
}
}
}

View file

@ -29,6 +29,8 @@ namespace Ryujinx
AOptimizations.DisableMemoryChecks = !Convert.ToBoolean(Parser.Value("Enable_Memory_Checks"));
AGraphicsConfig.ShadersDumpPath = Parser.Value("Graphics_Shaders_Dump_Path");
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.Info, Convert.ToBoolean(Parser.Value("Logging_Enable_Info")));

View file

@ -1,6 +1,9 @@
#Enable cpu memory checks (slow)
Enable_Memory_Checks = false
#Dump shaders in local directory (e.g. `C:\ShaderDumps`)
Graphics_Shaders_Dump_Path =
#Enable print debug logs
Logging_Enable_Debug = false