diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index efb0503ca..46a6ba98d 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/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); } /// @@ -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); } /// diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs index 4471fa322..e1f49065c 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs +++ b/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++) { diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/GlslGenerator.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/GlslGenerator.cs index 5e097b144..e1da1a567 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/GlslGenerator.cs +++ b/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;"); diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs index 9e79a0807..03d282564 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs +++ b/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}"; diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs index 4c6d17a05..c4d8370c2 100644 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs +++ b/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); diff --git a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs index 85ac2836d..b22eb5f12 100644 --- a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs +++ b/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(); _usedTextures = new Dictionary(); _usedImages = new Dictionary(); } - 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; diff --git a/Ryujinx.Graphics.Shader/Translation/TargetApi.cs b/Ryujinx.Graphics.Shader/Translation/TargetApi.cs new file mode 100644 index 000000000..6ac235a40 --- /dev/null +++ b/Ryujinx.Graphics.Shader/Translation/TargetApi.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Graphics.Shader.Translation +{ + public enum TargetApi + { + OpenGL, + Vulkan + } +} diff --git a/Ryujinx.Graphics.Shader/Translation/TargetLanguage.cs b/Ryujinx.Graphics.Shader/Translation/TargetLanguage.cs new file mode 100644 index 000000000..db839e949 --- /dev/null +++ b/Ryujinx.Graphics.Shader/Translation/TargetLanguage.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Graphics.Shader.Translation +{ + public enum TargetLanguage + { + Glsl, + Spirv + } +} diff --git a/Ryujinx.Graphics.Shader/Translation/TranslationOptions.cs b/Ryujinx.Graphics.Shader/Translation/TranslationOptions.cs new file mode 100644 index 000000000..532e9abb8 --- /dev/null +++ b/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; + } + } +} diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs index b250d3de3..0f71b5996 100644 --- a/Ryujinx.Graphics.Shader/Translation/Translator.cs +++ b/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; diff --git a/Ryujinx.ShaderTools/Program.cs b/Ryujinx.ShaderTools/Program.cs index 39b9425cf..17c242a91 100644 --- a/Ryujinx.ShaderTools/Program.cs +++ b/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); }