Browse Source

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

gdkchan 4 years ago
parent
commit
d125fce3e8

+ 13 - 6
Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs

@@ -192,7 +192,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
                                     {
                                         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) =>
@@ -298,8 +299,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
                                             {
                                                 IGpuAccessor gpuAccessor = new CachedGpuAccessor(_context, entry.Code, entry.Header.GpuAccessorHeader, entry.TextureDescriptors);
 
-                                                TranslatorContext translatorContext = Translator.CreateContext(0, gpuAccessor, flags, counts);
-                                                TranslatorContext translatorContext2 = Translator.CreateContext((ulong)entry.Header.Size, gpuAccessor, flags | TranslationFlags.VertexA, counts);
+                                                var options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, flags);
+                                                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);
                                             }
@@ -323,7 +327,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
                                             {
                                                 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);
@@ -851,7 +856,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
 
             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>
@@ -880,7 +886,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
 
             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>

+ 25 - 5
Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs

@@ -291,7 +291,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
 
             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.AppendLine("uint " + DefaultNames.DataName + "[];");
             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();
 
-                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),
                     indexExpr);
 
+                string imageTypeName = descriptor.Type.ToGlslImageType(descriptor.Format.GetComponentType());
+
                 string layout = descriptor.Format.ToGlslFormat();
 
                 if (!string.IsNullOrEmpty(layout))
@@ -363,7 +377,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
                     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};");
             }
@@ -411,7 +431,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
 
             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++)
                 {
@@ -463,7 +483,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
         {
             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++)
                 {

+ 1 - 1
Ryujinx.Graphics.Shader/CodeGen/Glsl/GlslGenerator.cs

@@ -74,7 +74,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
                             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}_y = 0.0;");

+ 1 - 1
Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs

@@ -156,7 +156,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
                     ? DefaultNames.OAttributePrefix
                     : DefaultNames.IAttributePrefix;
 
-                if ((config.Flags & TranslationFlags.Feedback) != 0)
+                if ((config.Options.Flags & TranslationFlags.Feedback) != 0)
                 {
                     string name = $"{prefix}{(value >> 4)}_{swzMask}";
 

+ 1 - 1
Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs

@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
 
             // When debug mode is enabled, we disable expression propagation
             // (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);
 

+ 4 - 4
Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs

@@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Shader.Translation
 
         public IGpuAccessor GpuAccessor { get; }
 
-        public TranslationFlags Flags { get; }
+        public TranslationOptions Options { get; }
 
         public int Size { get; private set; }
 
@@ -94,18 +94,18 @@ namespace Ryujinx.Graphics.Shader.Translation
         public int FirstConstantBufferBinding { 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;
             GpuAccessor            = gpuAccessor;
-            Flags                  = flags;
+            Options                = options;
             _counts                = counts;
             TextureHandlesForCache = new HashSet<int>();
             _usedTextures          = 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;
             GpPassthrough     = header.Stage == ShaderStage.Geometry && header.GpPassthrough;

+ 8 - 0
Ryujinx.Graphics.Shader/Translation/TargetApi.cs

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

+ 8 - 0
Ryujinx.Graphics.Shader/Translation/TargetLanguage.cs

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

+ 16 - 0
Ryujinx.Graphics.Shader/Translation/TranslationOptions.cs

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

+ 8 - 8
Ryujinx.Graphics.Shader/Translation/Translator.cs

@@ -26,12 +26,12 @@ namespace Ryujinx.Graphics.Shader.Translation
         public static TranslatorContext CreateContext(
             ulong address,
             IGpuAccessor gpuAccessor,
-            TranslationFlags flags,
+            TranslationOptions options,
             TranslationCounts counts = null)
         {
             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);
         }
@@ -103,7 +103,7 @@ namespace Ryujinx.Graphics.Shader.Translation
         private static Block[][] DecodeShader(
             ulong address,
             IGpuAccessor gpuAccessor,
-            TranslationFlags flags,
+            TranslationOptions options,
             TranslationCounts counts,
             out ShaderConfig config)
         {
@@ -112,15 +112,15 @@ namespace Ryujinx.Graphics.Shader.Translation
 
             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);
             }
             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);
             }
@@ -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;
         }
@@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Shader.Translation
             {
                 OpCode op = block.OpCodes[opIndex];
 
-                if ((context.Config.Flags & TranslationFlags.DebugMode) != 0)
+                if ((context.Config.Options.Flags & TranslationFlags.DebugMode) != 0)
                 {
                     string instName;
 

+ 2 - 1
Ryujinx.ShaderTools/Program.cs

@@ -36,7 +36,8 @@ namespace Ryujinx.ShaderTools
 
                 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);
             }