shadertools: Prepare for new target Languages and APIs (#2465)
* shadertools: Prepare for new target Langugaes and APIs This improves shader tools command line by adding support for target language and api. * Address gdkchan's comments
This commit is contained in:
parent
ca5ac37cd6
commit
97a2133207
5 changed files with 87 additions and 19 deletions
|
@ -7,13 +7,23 @@ namespace Ryujinx.Graphics.Shader
|
||||||
public ShaderStage Stage { get; }
|
public ShaderStage Stage { get; }
|
||||||
|
|
||||||
public string Code { get; private set; }
|
public string Code { get; private set; }
|
||||||
|
public byte[] BinaryCode { get; }
|
||||||
|
|
||||||
public ShaderProgram(ShaderStage stage, string code)
|
private ShaderProgram(ShaderStage stage)
|
||||||
{
|
{
|
||||||
Stage = stage;
|
Stage = stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShaderProgram(ShaderStage stage, string code) : this(stage)
|
||||||
|
{
|
||||||
Code = code;
|
Code = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ShaderProgram(ShaderStage stage, byte[] binaryCode) : this(stage)
|
||||||
|
{
|
||||||
|
BinaryCode = binaryCode;
|
||||||
|
}
|
||||||
|
|
||||||
public void Prepend(string line)
|
public void Prepend(string line)
|
||||||
{
|
{
|
||||||
Code = line + Environment.NewLine + Code;
|
Code = line + Environment.NewLine + Code;
|
||||||
|
|
|
@ -3,6 +3,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
public enum TargetLanguage
|
public enum TargetLanguage
|
||||||
{
|
{
|
||||||
Glsl,
|
Glsl,
|
||||||
Spirv
|
Spirv,
|
||||||
|
Arb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ using Ryujinx.Graphics.Shader.Decoders;
|
||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.StructuredIr;
|
using Ryujinx.Graphics.Shader.StructuredIr;
|
||||||
using Ryujinx.Graphics.Shader.Translation.Optimizations;
|
using Ryujinx.Graphics.Shader.Translation.Optimizations;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
@ -87,7 +88,16 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
|
||||||
StructuredProgramInfo sInfo = StructuredProgram.MakeStructuredProgram(funcs, config);
|
StructuredProgramInfo sInfo = StructuredProgram.MakeStructuredProgram(funcs, config);
|
||||||
|
|
||||||
string glslCode = GlslGenerator.Generate(sInfo, config);
|
ShaderProgram program;
|
||||||
|
|
||||||
|
switch (config.Options.TargetLanguage)
|
||||||
|
{
|
||||||
|
case TargetLanguage.Glsl:
|
||||||
|
program = new ShaderProgram(config.Stage, GlslGenerator.Generate(sInfo, config));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException(config.Options.TargetLanguage.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
shaderProgramInfo = new ShaderProgramInfo(
|
shaderProgramInfo = new ShaderProgramInfo(
|
||||||
config.GetConstantBufferDescriptors(),
|
config.GetConstantBufferDescriptors(),
|
||||||
|
@ -97,7 +107,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
config.UsedFeatures.HasFlag(FeatureFlags.InstanceId),
|
config.UsedFeatures.HasFlag(FeatureFlags.InstanceId),
|
||||||
config.ClipDistancesWritten);
|
config.ClipDistancesWritten);
|
||||||
|
|
||||||
return new ShaderProgram(config.Stage, glslCode);
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Block[][] DecodeShader(
|
private static Block[][] DecodeShader(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Ryujinx.Graphics.Shader;
|
using CommandLine;
|
||||||
|
using Ryujinx.Graphics.Shader;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -23,28 +24,70 @@ namespace Ryujinx.ShaderTools
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Main(string[] args)
|
private class Options
|
||||||
{
|
{
|
||||||
if (args.Length == 1 || args.Length == 2)
|
[Option("compute", Required = false, Default = false, HelpText = "Indicate that the shader is a compute shader.")]
|
||||||
|
public bool Compute { get; set; }
|
||||||
|
|
||||||
|
[Option("target-language", Required = false, Default = TargetLanguage.Glsl, HelpText = "Indicate the target shader language to use.")]
|
||||||
|
public TargetLanguage TargetLanguage { get; set; }
|
||||||
|
|
||||||
|
[Option("target-api", Required = false, Default = TargetApi.OpenGL, HelpText = "Indicate the target graphics api to use.")]
|
||||||
|
public TargetApi TargetApi { get; set; }
|
||||||
|
|
||||||
|
[Value(0, MetaName = "input", HelpText = "Binary Maxwell shader input path.", Required = true)]
|
||||||
|
public string InputPath { get; set; }
|
||||||
|
|
||||||
|
[Value(1, MetaName = "output", HelpText = "Decompiled shader output path.", Required = false)]
|
||||||
|
public string OutputPath { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HandleArguments(Options options)
|
||||||
{
|
{
|
||||||
TranslationFlags flags = TranslationFlags.DebugMode;
|
TranslationFlags flags = TranslationFlags.DebugMode;
|
||||||
|
|
||||||
if (args.Length == 2 && args[0] == "--compute")
|
if (options.Compute)
|
||||||
{
|
{
|
||||||
flags |= TranslationFlags.Compute;
|
flags |= TranslationFlags.Compute;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] data = File.ReadAllBytes(args[^1]);
|
byte[] data = File.ReadAllBytes(options.InputPath);
|
||||||
|
|
||||||
TranslationOptions options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, flags);
|
TranslationOptions translationOptions = new TranslationOptions(options.TargetLanguage, options.TargetApi, flags);
|
||||||
string code = Translator.CreateContext(0, new GpuAccessor(data), options).Translate(out _).Code;
|
|
||||||
|
|
||||||
Console.WriteLine(code);
|
ShaderProgram program = Translator.CreateContext(0, new GpuAccessor(data), translationOptions).Translate(out _);
|
||||||
|
|
||||||
|
if (options.OutputPath == null)
|
||||||
|
{
|
||||||
|
if (program.BinaryCode != null)
|
||||||
|
{
|
||||||
|
using Stream outputStream = Console.OpenStandardOutput();
|
||||||
|
|
||||||
|
outputStream.Write(program.BinaryCode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console.WriteLine("Usage: Ryujinx.ShaderTools [--compute] shader.bin");
|
Console.WriteLine(program.Code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (program.BinaryCode != null)
|
||||||
|
{
|
||||||
|
File.WriteAllBytes(options.OutputPath, program.BinaryCode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
File.WriteAllText(options.OutputPath, program.Code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Parser.Default.ParseArguments<Options>(args)
|
||||||
|
.WithParsed(options => HandleArguments(options))
|
||||||
|
.WithNotParsed(errors => errors.Output());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -11,4 +11,8 @@
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Shader\Ryujinx.Graphics.Shader.csproj" />
|
<ProjectReference Include="..\Ryujinx.Graphics.Shader\Ryujinx.Graphics.Shader.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CommandLineParser" Version="2.8.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
Reference in a new issue