Allow shader language and target API to be specified on the shader translator (#2402)
This commit is contained in:
parent
b0ac1ade7f
commit
d125fce3e8
11 changed files with 87 additions and 27 deletions
|
@ -192,7 +192,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
{
|
{
|
||||||
IGpuAccessor gpuAccessor = new CachedGpuAccessor(_context, entry.Code, entry.Header.GpuAccessorHeader, entry.TextureDescriptors);
|
IGpuAccessor gpuAccessor = new CachedGpuAccessor(_context, entry.Code, entry.Header.GpuAccessorHeader, entry.TextureDescriptors);
|
||||||
|
|
||||||
program = Translator.CreateContext(0, gpuAccessor, DefaultFlags | TranslationFlags.Compute).Translate(out shaderProgramInfo);
|
var options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, DefaultFlags | TranslationFlags.Compute);
|
||||||
|
program = Translator.CreateContext(0, gpuAccessor, options).Translate(out shaderProgramInfo);
|
||||||
});
|
});
|
||||||
|
|
||||||
task.OnTask(compileTask, (bool _, ShaderCompileTask task) =>
|
task.OnTask(compileTask, (bool _, ShaderCompileTask task) =>
|
||||||
|
@ -298,8 +299,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
{
|
{
|
||||||
IGpuAccessor gpuAccessor = new CachedGpuAccessor(_context, entry.Code, entry.Header.GpuAccessorHeader, entry.TextureDescriptors);
|
IGpuAccessor gpuAccessor = new CachedGpuAccessor(_context, entry.Code, entry.Header.GpuAccessorHeader, entry.TextureDescriptors);
|
||||||
|
|
||||||
TranslatorContext translatorContext = Translator.CreateContext(0, gpuAccessor, flags, counts);
|
var options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, flags);
|
||||||
TranslatorContext translatorContext2 = Translator.CreateContext((ulong)entry.Header.Size, gpuAccessor, flags | TranslationFlags.VertexA, counts);
|
var options2 = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, flags | TranslationFlags.VertexA);
|
||||||
|
|
||||||
|
TranslatorContext translatorContext = Translator.CreateContext(0, gpuAccessor, options, counts);
|
||||||
|
TranslatorContext translatorContext2 = Translator.CreateContext((ulong)entry.Header.Size, gpuAccessor, options2, counts);
|
||||||
|
|
||||||
program = translatorContext.Translate(out shaderProgramInfo, translatorContext2);
|
program = translatorContext.Translate(out shaderProgramInfo, translatorContext2);
|
||||||
}
|
}
|
||||||
|
@ -323,7 +327,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
{
|
{
|
||||||
IGpuAccessor gpuAccessor = new CachedGpuAccessor(_context, entry.Code, entry.Header.GpuAccessorHeader, entry.TextureDescriptors);
|
IGpuAccessor gpuAccessor = new CachedGpuAccessor(_context, entry.Code, entry.Header.GpuAccessorHeader, entry.TextureDescriptors);
|
||||||
|
|
||||||
program = Translator.CreateContext(0, gpuAccessor, flags, counts).Translate(out shaderProgramInfo);
|
var options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, flags);
|
||||||
|
program = Translator.CreateContext(0, gpuAccessor, options, counts).Translate(out shaderProgramInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
shaders[i] = new ShaderCodeHolder(program, shaderProgramInfo, entry.Code);
|
shaders[i] = new ShaderCodeHolder(program, shaderProgramInfo, entry.Code);
|
||||||
|
@ -851,7 +856,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
|
|
||||||
GpuAccessor gpuAccessor = new GpuAccessor(_context, state, localSizeX, localSizeY, localSizeZ, localMemorySize, sharedMemorySize);
|
GpuAccessor gpuAccessor = new GpuAccessor(_context, state, localSizeX, localSizeY, localSizeZ, localMemorySize, sharedMemorySize);
|
||||||
|
|
||||||
return Translator.CreateContext(gpuVa, gpuAccessor, DefaultFlags | TranslationFlags.Compute);
|
var options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, DefaultFlags | TranslationFlags.Compute);
|
||||||
|
return Translator.CreateContext(gpuVa, gpuAccessor, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -880,7 +886,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
|
|
||||||
GpuAccessor gpuAccessor = new GpuAccessor(_context, state, (int)stage - 1);
|
GpuAccessor gpuAccessor = new GpuAccessor(_context, state, (int)stage - 1);
|
||||||
|
|
||||||
return Translator.CreateContext(gpuVa, gpuAccessor, flags, counts);
|
var options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, flags);
|
||||||
|
return Translator.CreateContext(gpuVa, gpuAccessor, options, counts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -291,7 +291,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
|
|
||||||
string blockName = $"{sbName}_{DefaultNames.BlockSuffix}";
|
string blockName = $"{sbName}_{DefaultNames.BlockSuffix}";
|
||||||
|
|
||||||
context.AppendLine($"layout (binding = {context.Config.FirstStorageBufferBinding}, std430) buffer {blockName}");
|
string layout = context.Config.Options.TargetApi == TargetApi.Vulkan ? ", set = 1" : string.Empty;
|
||||||
|
|
||||||
|
context.AppendLine($"layout (binding = {context.Config.FirstStorageBufferBinding}{layout}, std430) buffer {blockName}");
|
||||||
context.EnterScope();
|
context.EnterScope();
|
||||||
context.AppendLine("uint " + DefaultNames.DataName + "[];");
|
context.AppendLine("uint " + DefaultNames.DataName + "[];");
|
||||||
context.LeaveScope($" {sbName}[{NumberFormatter.FormatInt(descriptors.Max(x => x.Slot) + 1)}];");
|
context.LeaveScope($" {sbName}[{NumberFormatter.FormatInt(descriptors.Max(x => x.Slot) + 1)}];");
|
||||||
|
@ -325,7 +327,17 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
|
|
||||||
string samplerTypeName = descriptor.Type.ToGlslSamplerType();
|
string samplerTypeName = descriptor.Type.ToGlslSamplerType();
|
||||||
|
|
||||||
context.AppendLine($"layout (binding = {descriptor.Binding}) uniform {samplerTypeName} {samplerName};");
|
string layout = string.Empty;
|
||||||
|
|
||||||
|
if (context.Config.Options.TargetApi == TargetApi.Vulkan)
|
||||||
|
{
|
||||||
|
bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer;
|
||||||
|
int setIndex = isBuffer ? 4 : 2;
|
||||||
|
|
||||||
|
layout = $", set = {setIndex}";
|
||||||
|
}
|
||||||
|
|
||||||
|
context.AppendLine($"layout (binding = {descriptor.Binding}{layout}) uniform {samplerTypeName} {samplerName};");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,6 +368,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
descriptor.Type.HasFlag(SamplerType.Indexed),
|
descriptor.Type.HasFlag(SamplerType.Indexed),
|
||||||
indexExpr);
|
indexExpr);
|
||||||
|
|
||||||
|
string imageTypeName = descriptor.Type.ToGlslImageType(descriptor.Format.GetComponentType());
|
||||||
|
|
||||||
string layout = descriptor.Format.ToGlslFormat();
|
string layout = descriptor.Format.ToGlslFormat();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(layout))
|
if (!string.IsNullOrEmpty(layout))
|
||||||
|
@ -363,7 +377,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
layout = ", " + layout;
|
layout = ", " + layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
string imageTypeName = descriptor.Type.ToGlslImageType(descriptor.Format.GetComponentType());
|
if (context.Config.Options.TargetApi == TargetApi.Vulkan)
|
||||||
|
{
|
||||||
|
bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer;
|
||||||
|
int setIndex = isBuffer ? 5 : 3;
|
||||||
|
|
||||||
|
layout = $", set = {setIndex}{layout}";
|
||||||
|
}
|
||||||
|
|
||||||
context.AppendLine($"layout (binding = {descriptor.Binding}{layout}) uniform {imageTypeName} {imageName};");
|
context.AppendLine($"layout (binding = {descriptor.Binding}{layout}) uniform {imageTypeName} {imageName};");
|
||||||
}
|
}
|
||||||
|
@ -411,7 +431,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
|
|
||||||
string name = $"{DefaultNames.IAttributePrefix}{attr}";
|
string name = $"{DefaultNames.IAttributePrefix}{attr}";
|
||||||
|
|
||||||
if ((context.Config.Flags & TranslationFlags.Feedback) != 0)
|
if ((context.Config.Options.Flags & TranslationFlags.Feedback) != 0)
|
||||||
{
|
{
|
||||||
for (int c = 0; c < 4; c++)
|
for (int c = 0; c < 4; c++)
|
||||||
{
|
{
|
||||||
|
@ -463,7 +483,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
{
|
{
|
||||||
string name = $"{DefaultNames.OAttributePrefix}{attr}";
|
string name = $"{DefaultNames.OAttributePrefix}{attr}";
|
||||||
|
|
||||||
if ((context.Config.Flags & TranslationFlags.Feedback) != 0)
|
if ((context.Config.Options.Flags & TranslationFlags.Feedback) != 0)
|
||||||
{
|
{
|
||||||
for (int c = 0; c < 4; c++)
|
for (int c = 0; c < 4; c++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((context.Config.Flags & TranslationFlags.Feedback) != 0)
|
if ((context.Config.Options.Flags & TranslationFlags.Feedback) != 0)
|
||||||
{
|
{
|
||||||
context.AppendLine($"{DefaultNames.OAttributePrefix}{attr}_x = 0.0;");
|
context.AppendLine($"{DefaultNames.OAttributePrefix}{attr}_x = 0.0;");
|
||||||
context.AppendLine($"{DefaultNames.OAttributePrefix}{attr}_y = 0.0;");
|
context.AppendLine($"{DefaultNames.OAttributePrefix}{attr}_y = 0.0;");
|
||||||
|
|
|
@ -156,7 +156,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
? DefaultNames.OAttributePrefix
|
? DefaultNames.OAttributePrefix
|
||||||
: DefaultNames.IAttributePrefix;
|
: DefaultNames.IAttributePrefix;
|
||||||
|
|
||||||
if ((config.Flags & TranslationFlags.Feedback) != 0)
|
if ((config.Options.Flags & TranslationFlags.Feedback) != 0)
|
||||||
{
|
{
|
||||||
string name = $"{prefix}{(value >> 4)}_{swzMask}";
|
string name = $"{prefix}{(value >> 4)}_{swzMask}";
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||||
|
|
||||||
// When debug mode is enabled, we disable expression propagation
|
// When debug mode is enabled, we disable expression propagation
|
||||||
// (this makes comparison with the disassembly easier).
|
// (this makes comparison with the disassembly easier).
|
||||||
if ((context.Config.Flags & TranslationFlags.DebugMode) == 0)
|
if ((context.Config.Options.Flags & TranslationFlags.DebugMode) == 0)
|
||||||
{
|
{
|
||||||
AstBlockVisitor visitor = new AstBlockVisitor(mainBlock);
|
AstBlockVisitor visitor = new AstBlockVisitor(mainBlock);
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
|
||||||
public IGpuAccessor GpuAccessor { get; }
|
public IGpuAccessor GpuAccessor { get; }
|
||||||
|
|
||||||
public TranslationFlags Flags { get; }
|
public TranslationOptions Options { get; }
|
||||||
|
|
||||||
public int Size { get; private set; }
|
public int Size { get; private set; }
|
||||||
|
|
||||||
|
@ -94,18 +94,18 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
public int FirstConstantBufferBinding { get; private set; }
|
public int FirstConstantBufferBinding { get; private set; }
|
||||||
public int FirstStorageBufferBinding { get; private set; }
|
public int FirstStorageBufferBinding { get; private set; }
|
||||||
|
|
||||||
public ShaderConfig(IGpuAccessor gpuAccessor, TranslationFlags flags, TranslationCounts counts)
|
public ShaderConfig(IGpuAccessor gpuAccessor, TranslationOptions options, TranslationCounts counts)
|
||||||
{
|
{
|
||||||
Stage = ShaderStage.Compute;
|
Stage = ShaderStage.Compute;
|
||||||
GpuAccessor = gpuAccessor;
|
GpuAccessor = gpuAccessor;
|
||||||
Flags = flags;
|
Options = options;
|
||||||
_counts = counts;
|
_counts = counts;
|
||||||
TextureHandlesForCache = new HashSet<int>();
|
TextureHandlesForCache = new HashSet<int>();
|
||||||
_usedTextures = new Dictionary<TextureInfo, TextureMeta>();
|
_usedTextures = new Dictionary<TextureInfo, TextureMeta>();
|
||||||
_usedImages = new Dictionary<TextureInfo, TextureMeta>();
|
_usedImages = new Dictionary<TextureInfo, TextureMeta>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationFlags flags, TranslationCounts counts) : this(gpuAccessor, flags, counts)
|
public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationOptions options, TranslationCounts counts) : this(gpuAccessor, options, counts)
|
||||||
{
|
{
|
||||||
Stage = header.Stage;
|
Stage = header.Stage;
|
||||||
GpPassthrough = header.Stage == ShaderStage.Geometry && header.GpPassthrough;
|
GpPassthrough = header.Stage == ShaderStage.Geometry && header.GpPassthrough;
|
||||||
|
|
8
Ryujinx.Graphics.Shader/Translation/TargetApi.cs
Normal file
8
Ryujinx.Graphics.Shader/Translation/TargetApi.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
{
|
||||||
|
public enum TargetApi
|
||||||
|
{
|
||||||
|
OpenGL,
|
||||||
|
Vulkan
|
||||||
|
}
|
||||||
|
}
|
8
Ryujinx.Graphics.Shader/Translation/TargetLanguage.cs
Normal file
8
Ryujinx.Graphics.Shader/Translation/TargetLanguage.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
{
|
||||||
|
public enum TargetLanguage
|
||||||
|
{
|
||||||
|
Glsl,
|
||||||
|
Spirv
|
||||||
|
}
|
||||||
|
}
|
16
Ryujinx.Graphics.Shader/Translation/TranslationOptions.cs
Normal file
16
Ryujinx.Graphics.Shader/Translation/TranslationOptions.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
{
|
||||||
|
public struct TranslationOptions
|
||||||
|
{
|
||||||
|
public TargetLanguage TargetLanguage { get; }
|
||||||
|
public TargetApi TargetApi { get; }
|
||||||
|
public TranslationFlags Flags { get; }
|
||||||
|
|
||||||
|
public TranslationOptions(TargetLanguage targetLanguage, TargetApi targetApi, TranslationFlags flags)
|
||||||
|
{
|
||||||
|
TargetLanguage = targetLanguage;
|
||||||
|
TargetApi = targetApi;
|
||||||
|
Flags = flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,12 +26,12 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
public static TranslatorContext CreateContext(
|
public static TranslatorContext CreateContext(
|
||||||
ulong address,
|
ulong address,
|
||||||
IGpuAccessor gpuAccessor,
|
IGpuAccessor gpuAccessor,
|
||||||
TranslationFlags flags,
|
TranslationOptions options,
|
||||||
TranslationCounts counts = null)
|
TranslationCounts counts = null)
|
||||||
{
|
{
|
||||||
counts ??= new TranslationCounts();
|
counts ??= new TranslationCounts();
|
||||||
|
|
||||||
Block[][] cfg = DecodeShader(address, gpuAccessor, flags, counts, out ShaderConfig config);
|
Block[][] cfg = DecodeShader(address, gpuAccessor, options, counts, out ShaderConfig config);
|
||||||
|
|
||||||
return new TranslatorContext(address, cfg, config);
|
return new TranslatorContext(address, cfg, config);
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
private static Block[][] DecodeShader(
|
private static Block[][] DecodeShader(
|
||||||
ulong address,
|
ulong address,
|
||||||
IGpuAccessor gpuAccessor,
|
IGpuAccessor gpuAccessor,
|
||||||
TranslationFlags flags,
|
TranslationOptions options,
|
||||||
TranslationCounts counts,
|
TranslationCounts counts,
|
||||||
out ShaderConfig config)
|
out ShaderConfig config)
|
||||||
{
|
{
|
||||||
|
@ -112,15 +112,15 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
|
||||||
bool hasBindless;
|
bool hasBindless;
|
||||||
|
|
||||||
if ((flags & TranslationFlags.Compute) != 0)
|
if ((options.Flags & TranslationFlags.Compute) != 0)
|
||||||
{
|
{
|
||||||
config = new ShaderConfig(gpuAccessor, flags, counts);
|
config = new ShaderConfig(gpuAccessor, options, counts);
|
||||||
|
|
||||||
cfg = Decoder.Decode(gpuAccessor, address, out hasBindless);
|
cfg = Decoder.Decode(gpuAccessor, address, out hasBindless);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
config = new ShaderConfig(new ShaderHeader(gpuAccessor, address), gpuAccessor, flags, counts);
|
config = new ShaderConfig(new ShaderHeader(gpuAccessor, address), gpuAccessor, options, counts);
|
||||||
|
|
||||||
cfg = Decoder.Decode(gpuAccessor, address + HeaderSize, out hasBindless);
|
cfg = Decoder.Decode(gpuAccessor, address + HeaderSize, out hasBindless);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config.SizeAdd((int)maxEndAddress + (flags.HasFlag(TranslationFlags.Compute) ? 0 : HeaderSize));
|
config.SizeAdd((int)maxEndAddress + (options.Flags.HasFlag(TranslationFlags.Compute) ? 0 : HeaderSize));
|
||||||
|
|
||||||
return cfg;
|
return cfg;
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
{
|
{
|
||||||
OpCode op = block.OpCodes[opIndex];
|
OpCode op = block.OpCodes[opIndex];
|
||||||
|
|
||||||
if ((context.Config.Flags & TranslationFlags.DebugMode) != 0)
|
if ((context.Config.Options.Flags & TranslationFlags.DebugMode) != 0)
|
||||||
{
|
{
|
||||||
string instName;
|
string instName;
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,8 @@ namespace Ryujinx.ShaderTools
|
||||||
|
|
||||||
byte[] data = File.ReadAllBytes(args[^1]);
|
byte[] data = File.ReadAllBytes(args[^1]);
|
||||||
|
|
||||||
string code = Translator.CreateContext(0, new GpuAccessor(data), flags).Translate(out _).Code;
|
TranslationOptions options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, flags);
|
||||||
|
string code = Translator.CreateContext(0, new GpuAccessor(data), options).Translate(out _).Code;
|
||||||
|
|
||||||
Console.WriteLine(code);
|
Console.WriteLine(code);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue