Program.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using CommandLine;
  2. using Ryujinx.Graphics.Shader;
  3. using Ryujinx.Graphics.Shader.Translation;
  4. using System;
  5. using System.IO;
  6. using System.Runtime.InteropServices;
  7. namespace Ryujinx.ShaderTools
  8. {
  9. class Program
  10. {
  11. private class GpuAccessor : IGpuAccessor
  12. {
  13. private readonly byte[] _data;
  14. public GpuAccessor(byte[] data)
  15. {
  16. _data = data;
  17. }
  18. public ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize)
  19. {
  20. return MemoryMarshal.Cast<byte, ulong>(new ReadOnlySpan<byte>(_data).Slice((int)address));
  21. }
  22. }
  23. private class Options
  24. {
  25. [Option("compute", Required = false, Default = false, HelpText = "Indicate that the shader is a compute shader.")]
  26. public bool Compute { get; set; }
  27. [Option("target-language", Required = false, Default = TargetLanguage.Glsl, HelpText = "Indicate the target shader language to use.")]
  28. public TargetLanguage TargetLanguage { get; set; }
  29. [Option("target-api", Required = false, Default = TargetApi.OpenGL, HelpText = "Indicate the target graphics api to use.")]
  30. public TargetApi TargetApi { get; set; }
  31. [Value(0, MetaName = "input", HelpText = "Binary Maxwell shader input path.", Required = true)]
  32. public string InputPath { get; set; }
  33. [Value(1, MetaName = "output", HelpText = "Decompiled shader output path.", Required = false)]
  34. public string OutputPath { get; set; }
  35. }
  36. static void HandleArguments(Options options)
  37. {
  38. TranslationFlags flags = TranslationFlags.DebugMode;
  39. if (options.Compute)
  40. {
  41. flags |= TranslationFlags.Compute;
  42. }
  43. byte[] data = File.ReadAllBytes(options.InputPath);
  44. TranslationOptions translationOptions = new TranslationOptions(options.TargetLanguage, options.TargetApi, flags);
  45. ShaderProgram program = Translator.CreateContext(0, new GpuAccessor(data), translationOptions).Translate();
  46. if (options.OutputPath == null)
  47. {
  48. if (program.BinaryCode != null)
  49. {
  50. using Stream outputStream = Console.OpenStandardOutput();
  51. outputStream.Write(program.BinaryCode);
  52. }
  53. else
  54. {
  55. Console.WriteLine(program.Code);
  56. }
  57. }
  58. else
  59. {
  60. if (program.BinaryCode != null)
  61. {
  62. File.WriteAllBytes(options.OutputPath, program.BinaryCode);
  63. }
  64. else
  65. {
  66. File.WriteAllText(options.OutputPath, program.Code);
  67. }
  68. }
  69. }
  70. static void Main(string[] args)
  71. {
  72. Parser.Default.ParseArguments<Options>(args)
  73. .WithParsed(options => HandleArguments(options))
  74. .WithNotParsed(errors => errors.Output());
  75. }
  76. }
  77. }