0
0
Fork 0

Allow shader language and target API to be specified on the shader translator (#2402)

This commit is contained in:
gdkchan 2021-07-06 16:20:06 -03:00 committed by GitHub
parent b0ac1ade7f
commit d125fce3e8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 87 additions and 27 deletions

View file

@ -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>

View file

@ -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++)
{ {

View file

@ -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;");

View file

@ -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}";

View file

@ -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);

View file

@ -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;

View file

@ -0,0 +1,8 @@
namespace Ryujinx.Graphics.Shader.Translation
{
public enum TargetApi
{
OpenGL,
Vulkan
}
}

View file

@ -0,0 +1,8 @@
namespace Ryujinx.Graphics.Shader.Translation
{
public enum TargetLanguage
{
Glsl,
Spirv
}
}

View 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;
}
}
}

View file

@ -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;

View file

@ -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);
} }