diff options
Diffstat (limited to 'Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs')
-rw-r--r-- | Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs | 95 |
1 files changed, 65 insertions, 30 deletions
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs index 54578b79..f9dfb839 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs @@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl { public static void Declare(CodeGenContext context, StructuredProgramInfo info) { - context.AppendLine("#version 450 core"); + context.AppendLine(context.Config.Options.TargetApi == TargetApi.Vulkan ? "#version 460 core" : "#version 450 core"); context.AppendLine("#extension GL_ARB_gpu_shader_int64 : enable"); if (context.Config.GpuAccessor.QueryHostSupportsShaderBallot()) @@ -43,8 +43,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl context.AppendLine("#extension GL_INTEL_fragment_shader_ordering : enable"); } } + else + { + context.AppendLine("#extension GL_ARB_shader_viewport_layer_array : enable"); + } - if (context.Config.GpPassthrough) + if (context.Config.GpPassthrough && context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough()) { context.AppendLine("#extension GL_NV_geometry_shader_passthrough : enable"); } @@ -123,11 +127,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl { if (context.Config.Stage == ShaderStage.Geometry) { - string inPrimitive = context.Config.GpuAccessor.QueryPrimitiveTopology().ToGlslString(); + InputTopology inputTopology = context.Config.GpuAccessor.QueryPrimitiveTopology(); + string inPrimitive = inputTopology.ToGlslString(); - context.AppendLine($"layout ({inPrimitive}) in;"); + context.AppendLine($"layout (invocations = {context.Config.ThreadsPerInputPrimitive}, {inPrimitive}) in;"); - if (context.Config.GpPassthrough) + if (context.Config.GpPassthrough && context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough()) { context.AppendLine($"layout (passthrough) in gl_PerVertex"); context.EnterScope(); @@ -140,7 +145,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl { string outPrimitive = context.Config.OutputTopology.ToGlslString(); - int maxOutputVertices = context.Config.MaxOutputVertices; + int maxOutputVertices = context.Config.GpPassthrough + ? inputTopology.ToInputVertices() + : context.Config.MaxOutputVertices; context.AppendLine($"layout ({outPrimitive}, max_vertices = {maxOutputVertices}) out;"); } @@ -192,9 +199,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl context.AppendLine(); } - if (context.Config.Stage != ShaderStage.Compute && - context.Config.Stage != ShaderStage.Fragment && - context.Config.TransformFeedbackEnabled) + if (context.Config.TransformFeedbackEnabled && context.Config.LastInVertexPipeline) { var tfOutput = context.GetTransformFeedbackOutput(AttributeConsts.PositionX); if (tfOutput.Valid) @@ -311,6 +316,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl } } + private static string GetTfLayout(TransformFeedbackOutput tfOutput) + { + if (tfOutput.Valid) + { + return $"layout (xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}) "; + } + + return string.Empty; + } + public static void DeclareLocals(CodeGenContext context, StructuredFunction function) { foreach (AstOperand decl in function.Locals) @@ -326,11 +341,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl switch (type) { case VariableType.Bool: return "bool"; - case VariableType.F32: return "precise float"; - case VariableType.F64: return "double"; + case VariableType.F32: return "precise float"; + case VariableType.F64: return "double"; case VariableType.None: return "void"; - case VariableType.S32: return "int"; - case VariableType.U32: return "uint"; + case VariableType.S32: return "int"; + case VariableType.U32: return "uint"; } throw new ArgumentException($"Invalid variable type \"{type}\"."); @@ -417,10 +432,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl if (context.Config.Options.TargetApi == TargetApi.Vulkan) { - bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer; - int setIndex = isBuffer ? 4 : 2; - - layout = $", set = {setIndex}"; + layout = ", set = 2"; } context.AppendLine($"layout (binding = {descriptor.Binding}{layout}) uniform {samplerTypeName} {samplerName};"); @@ -470,10 +482,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl if (context.Config.Options.TargetApi == TargetApi.Vulkan) { - bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer; - int setIndex = isBuffer ? 5 : 3; - - layout = $", set = {setIndex}{layout}"; + layout = $", set = 3{layout}"; } context.AppendLine($"layout (binding = {descriptor.Binding}{layout}) uniform {imageTypeName} {imageName};"); @@ -512,7 +521,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl private static void DeclareInputAttribute(CodeGenContext context, StructuredProgramInfo info, int attr) { - string suffix = OperandManager.IsArrayAttribute(context.Config.Stage, isOutAttr: false) ? "[]" : string.Empty; + string suffix = AttributeInfo.IsArrayAttributeGlsl(context.Config.Stage, isOutAttr: false) ? "[]" : string.Empty; string iq = string.Empty; if (context.Config.Stage == ShaderStage.Fragment) @@ -525,29 +534,48 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl }; } - string pass = (context.Config.PassthroughAttributes & (1 << attr)) != 0 ? "passthrough, " : string.Empty; string name = $"{DefaultNames.IAttributePrefix}{attr}"; - if (context.Config.TransformFeedbackEnabled && context.Config.Stage != ShaderStage.Vertex) + if (context.Config.TransformFeedbackEnabled && context.Config.Stage == ShaderStage.Fragment) { for (int c = 0; c < 4; c++) { char swzMask = "xyzw"[c]; - context.AppendLine($"layout ({pass}location = {attr}, component = {c}) {iq}in float {name}_{swzMask}{suffix};"); + context.AppendLine($"layout (location = {attr}, component = {c}) {iq}in float {name}_{swzMask}{suffix};"); } } else { - context.AppendLine($"layout ({pass}location = {attr}) {iq}in vec4 {name}{suffix};"); + bool passthrough = (context.Config.PassthroughAttributes & (1 << attr)) != 0; + string pass = passthrough && context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough() ? "passthrough, " : string.Empty; + string type; + + if (context.Config.Stage == ShaderStage.Vertex) + { + type = context.Config.GpuAccessor.QueryAttributeType(attr).GetVec4Type(); + } + else + { + type = AttributeType.Float.GetVec4Type(); + } + + context.AppendLine($"layout ({pass}location = {attr}) {iq}in {type} {name}{suffix};"); } } private static void DeclareInputAttributePerPatch(CodeGenContext context, int attr) { + string layout = string.Empty; + + if (context.Config.Options.TargetApi == TargetApi.Vulkan) + { + layout = $"layout (location = {32 + attr}) "; + } + string name = $"{DefaultNames.PerPatchAttributePrefix}{attr}"; - context.AppendLine($"patch in vec4 {name};"); + context.AppendLine($"{layout}patch in vec4 {name};"); } private static void DeclareOutputAttributes(CodeGenContext context, StructuredProgramInfo info) @@ -570,10 +598,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl private static void DeclareOutputAttribute(CodeGenContext context, int attr) { - string suffix = OperandManager.IsArrayAttribute(context.Config.Stage, isOutAttr: true) ? "[]" : string.Empty; + string suffix = AttributeInfo.IsArrayAttributeGlsl(context.Config.Stage, isOutAttr: true) ? "[]" : string.Empty; string name = $"{DefaultNames.OAttributePrefix}{attr}{suffix}"; - if (context.Config.TransformFeedbackEnabled && context.Config.Stage != ShaderStage.Fragment) + if (context.Config.TransformFeedbackEnabled && context.Config.LastInVertexPipeline) { for (int c = 0; c < 4; c++) { @@ -608,9 +636,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl private static void DeclareOutputAttributePerPatch(CodeGenContext context, int attr) { + string layout = string.Empty; + + if (context.Config.Options.TargetApi == TargetApi.Vulkan) + { + layout = $"layout (location = {32 + attr}) "; + } + string name = $"{DefaultNames.PerPatchAttributePrefix}{attr}"; - context.AppendLine($"patch out vec4 {name};"); + context.AppendLine($"{layout}patch out vec4 {name};"); } private static void DeclareSupportUniformBlock(CodeGenContext context, ShaderStage stage, int scaleElements) |