diff --git a/Ryujinx.Graphics/Gal/OpenGL/OglShader.cs b/Ryujinx.Graphics/Gal/OpenGL/OglShader.cs index d6caeb9d97..1cd4b22c12 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OglShader.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OglShader.cs @@ -52,28 +52,30 @@ namespace Ryujinx.Graphics.Gal.OpenGL bool isDualVp, GalShaderType type) { - ShaderProgram program; + ShaderConfig config = new ShaderConfig(type, OglLimit.MaxUboSize); - int shaderDumpIndex = ShaderDumper.DumpIndex; + ShaderProgram program; if (isDualVp) { ShaderDumper.Dump(memory, position, type, "a"); ShaderDumper.Dump(memory, positionB, type, "b"); - program = Translator.Translate(memory, (ulong)position, (ulong)positionB, type); + program = Translator.Translate(memory, (ulong)position, (ulong)positionB, config); } else { ShaderDumper.Dump(memory, position, type); - program = Translator.Translate(memory, (ulong)position, type); + program = Translator.Translate(memory, (ulong)position, config); } string code = program.Code; if (ShaderDumper.IsDumpEnabled()) { + int shaderDumpIndex = ShaderDumper.DumpIndex; + code = "//Shader " + shaderDumpIndex + Environment.NewLine + code; } diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs index 9e849bccee..1f1b9bf7cf 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/CodeGenContext.cs @@ -1,4 +1,3 @@ -using Ryujinx.Graphics.Gal; using Ryujinx.Graphics.Shader.StructuredIr; using System.Collections.Generic; using System.Text; @@ -9,7 +8,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl { private const string Tab = " "; - public GalShaderType ShaderType { get; } + public ShaderConfig Config { get; } public List CBufferDescriptors { get; } public List TextureDescriptors { get; } @@ -22,9 +21,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl private string _identation; - public CodeGenContext(GalShaderType shaderType) + public CodeGenContext(ShaderConfig config) { - ShaderType = shaderType; + Config = config; CBufferDescriptors = new List(); TextureDescriptors = new List(); diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs index e80da36bb7..8e7280e6bb 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs @@ -19,7 +19,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl context.AppendLine(); - if (context.ShaderType == GalShaderType.Geometry) + if (context.Config.Type == GalShaderType.Geometry) { context.AppendLine("layout (points) in;"); context.AppendLine("layout (triangle_strip, max_vertices = 4) out;"); @@ -94,7 +94,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl { foreach (int cbufSlot in info.CBuffers.OrderBy(x => x)) { - string ubName = OperandManager.GetShaderStagePrefix(context.ShaderType); + string ubName = OperandManager.GetShaderStagePrefix(context.Config.Type); ubName += "_" + DefaultNames.UniformNamePrefix + cbufSlot; @@ -104,7 +104,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl context.EnterScope(); - context.AppendLine("vec4 " + OperandManager.GetUbName(context.ShaderType, cbufSlot) + "[4096];"); + string ubSize = "[" + NumberFormatter.FormatInt(context.Config.MaxCBufferSize / 16) + "]"; + + context.AppendLine("vec4 " + OperandManager.GetUbName(context.Config.Type, cbufSlot) + ubSize + ";"); context.LeaveScope(";"); } @@ -116,7 +118,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl foreach (AstTextureOperation texOp in info.Samplers.OrderBy(x => x.Handle)) { - string samplerName = OperandManager.GetSamplerName(context.ShaderType, texOp); + string samplerName = OperandManager.GetSamplerName(context.Config.Type, texOp); if (!samplers.TryAdd(samplerName, texOp)) { @@ -153,7 +155,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl private static void DeclareInputAttributes(CodeGenContext context, StructuredProgramInfo info) { - string suffix = context.ShaderType == GalShaderType.Geometry ? "[]" : string.Empty; + string suffix = context.Config.Type == GalShaderType.Geometry ? "[]" : string.Empty; foreach (int attr in info.IAttributes.OrderBy(x => x)) { diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs index 89672f6cfe..eb1e748e31 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/GlslGenerator.cs @@ -10,9 +10,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl { static class GlslGenerator { - public static GlslProgram Generate(StructuredProgramInfo info, GalShaderType shaderType) + public static GlslProgram Generate(StructuredProgramInfo info, ShaderConfig config) { - CodeGenContext context = new CodeGenContext(shaderType); + CodeGenContext context = new CodeGenContext(config); Declarations.Declare(context, info); @@ -124,7 +124,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl private static void PrepareForReturn(CodeGenContext context) { - if (context.ShaderType == GalShaderType.Vertex) + if (context.Config.Type == GalShaderType.Vertex) { context.AppendLine("gl_Position.xy *= flip;"); } diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs index 8a0d66301d..62d4b36c2c 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGen.cs @@ -26,7 +26,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions return NumberFormatter.FormatInt(operand.Value); case OperandType.ConstantBuffer: - return OperandManager.GetConstantBufferName(context.ShaderType, operand); + return OperandManager.GetConstantBufferName(context.Config.Type, operand); case OperandType.LocalVariable: return context.GetLocalName(operand); diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs index d2cc533a6c..4c48683905 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs @@ -34,7 +34,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions bool isMultisample = (texOp.Type & TextureType.Multisample) != 0; bool isShadow = (texOp.Type & TextureType.Shadow) != 0; - string samplerName = OperandManager.GetSamplerName(context.ShaderType, texOp); + string samplerName = OperandManager.GetSamplerName(context.Config.Type, texOp); string texCall = intCoords ? "texelFetch" : "texture"; @@ -195,7 +195,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0; - string samplerName = OperandManager.GetSamplerName(context.ShaderType, texOp); + string samplerName = OperandManager.GetSamplerName(context.Config.Type, texOp); IAstNode src0 = operation.GetSource(isBindless ? 1 : 0); diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs index 4bd8d14a17..d6e7ebf667 100644 --- a/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs +++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/OperandManager.cs @@ -60,7 +60,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl //slot access. AstOperand operand = (AstOperand)slot; - string ubName = GetUbName(context.ShaderType, operand.Value); + string ubName = GetUbName(context.Config.Type, operand.Value); string index0 = "[" + offsetExpr + " >> 4]"; string index1 = "[" + offsetExpr + " >> 2 & 3]"; @@ -90,7 +90,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl string name = $"{prefix}{(value >> 4)}"; - if (context.ShaderType == GalShaderType.Geometry && !isOutAttr) + if (context.Config.Type == GalShaderType.Geometry && !isOutAttr) { name += "[0]"; } @@ -111,7 +111,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl else if (_builtInAttributes.TryGetValue(value & ~3, out BuiltInAttribute builtInAttr)) { //TODO: There must be a better way to handle this... - if (context.ShaderType == GalShaderType.Fragment) + if (context.Config.Type == GalShaderType.Fragment) { switch (value & ~3) { @@ -124,7 +124,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl string name = builtInAttr.Name; - if (context.ShaderType == GalShaderType.Geometry && !isOutAttr) + if (context.Config.Type == GalShaderType.Geometry && !isOutAttr) { name = "gl_in[0]." + name; } diff --git a/Ryujinx.Graphics/Shader/ShaderConfig.cs b/Ryujinx.Graphics/Shader/ShaderConfig.cs new file mode 100644 index 0000000000..c2a94814e9 --- /dev/null +++ b/Ryujinx.Graphics/Shader/ShaderConfig.cs @@ -0,0 +1,23 @@ +using Ryujinx.Graphics.Gal; +using System; + +namespace Ryujinx.Graphics.Shader +{ + public struct ShaderConfig + { + public GalShaderType Type { get; } + + public int MaxCBufferSize; + + public ShaderConfig(GalShaderType type, int maxCBufferSize) + { + if (maxCBufferSize <= 0) + { + throw new ArgumentOutOfRangeException(nameof(maxCBufferSize)); + } + + Type = type; + MaxCBufferSize = maxCBufferSize; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Translation/Translator.cs b/Ryujinx.Graphics/Shader/Translation/Translator.cs index 225547d1be..706f3cfa4e 100644 --- a/Ryujinx.Graphics/Shader/Translation/Translator.cs +++ b/Ryujinx.Graphics/Shader/Translation/Translator.cs @@ -13,23 +13,23 @@ namespace Ryujinx.Graphics.Shader.Translation { public static class Translator { - public static ShaderProgram Translate(IGalMemory memory, ulong address, GalShaderType shaderType) + public static ShaderProgram Translate(IGalMemory memory, ulong address, ShaderConfig config) { - return Translate(memory, address, 0, shaderType); + return Translate(memory, address, 0, config); } public static ShaderProgram Translate( - IGalMemory memory, - ulong address, - ulong addressB, - GalShaderType shaderType) + IGalMemory memory, + ulong address, + ulong addressB, + ShaderConfig config) { - Operation[] shaderOps = DecodeShader(memory, address, shaderType); + Operation[] shaderOps = DecodeShader(memory, address, config.Type); if (addressB != 0) { //Dual vertex shader. - Operation[] shaderOpsB = DecodeShader(memory, addressB, shaderType); + Operation[] shaderOpsB = DecodeShader(memory, addressB, config.Type); shaderOps = Combine(shaderOps, shaderOpsB); } @@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Shader.Translation StructuredProgramInfo sInfo = StructuredProgram.MakeStructuredProgram(irBlocks); - GlslProgram program = GlslGenerator.Generate(sInfo, shaderType); + GlslProgram program = GlslGenerator.Generate(sInfo, config); ShaderProgramInfo spInfo = new ShaderProgramInfo( program.CBufferDescriptors, diff --git a/Ryujinx.ShaderTools/Program.cs b/Ryujinx.ShaderTools/Program.cs index 56b647b10c..e763e2c1c1 100644 --- a/Ryujinx.ShaderTools/Program.cs +++ b/Ryujinx.ShaderTools/Program.cs @@ -1,4 +1,5 @@ using Ryujinx.Graphics.Gal; +using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader.Translation; using System; using System.IO; @@ -26,7 +27,9 @@ namespace Ryujinx.ShaderTools { Memory mem = new Memory(fs); - string code = Translator.Translate(mem, 0, type).Code; + ShaderConfig config = new ShaderConfig(type, 65536); + + string code = Translator.Translate(mem, 0, config).Code; Console.WriteLine(code); }