diff options
Diffstat (limited to 'Ryujinx.Graphics.Shader/CodeGen')
6 files changed, 104 insertions, 84 deletions
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs index 65e78121..ff808b04 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs @@ -2,6 +2,7 @@ using Ryujinx.Common; using Ryujinx.Graphics.Shader.StructuredIr; using Ryujinx.Graphics.Shader.Translation; using System; +using System.Collections.Generic; using System.Linq; using System.Numerics; @@ -163,9 +164,17 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl } else if (context.Config.Stage == ShaderStage.TessellationEvaluation) { + bool tessCw = context.Config.GpuAccessor.QueryTessCw(); + + if (context.Config.Options.TargetApi == TargetApi.Vulkan) + { + // We invert the front face on Vulkan backend, so we need to do that here aswell. + tessCw = !tessCw; + } + string patchType = context.Config.GpuAccessor.QueryTessPatchType().ToGlsl(); string spacing = context.Config.GpuAccessor.QueryTessSpacing().ToGlsl(); - string windingOrder = context.Config.GpuAccessor.QueryTessCw() ? "cw" : "ccw"; + string windingOrder = tessCw ? "cw" : "ccw"; context.AppendLine($"layout ({patchType}, {spacing}, {windingOrder}) in;"); context.AppendLine(); @@ -185,14 +194,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl context.AppendLine(); } - if (context.Config.UsedInputAttributesPerPatch != 0) + if (context.Config.UsedInputAttributesPerPatch.Count != 0) { DeclareInputAttributesPerPatch(context, context.Config.UsedInputAttributesPerPatch); context.AppendLine(); } - if (context.Config.UsedOutputAttributesPerPatch != 0) + if (context.Config.UsedOutputAttributesPerPatch.Count != 0) { DeclareUsedOutputAttributesPerPatch(context, context.Config.UsedOutputAttributesPerPatch); @@ -509,13 +518,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl } } - private static void DeclareInputAttributesPerPatch(CodeGenContext context, int usedAttributes) + private static void DeclareInputAttributesPerPatch(CodeGenContext context, HashSet<int> attrs) { - while (usedAttributes != 0) + foreach (int attr in attrs.OrderBy(x => x)) { - int index = BitOperations.TrailingZeroCount(usedAttributes); - DeclareInputAttributePerPatch(context, index); - usedAttributes &= ~(1 << index); + DeclareInputAttributePerPatch(context, attr); } } @@ -566,16 +573,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl private static void DeclareInputAttributePerPatch(CodeGenContext context, int attr) { - string layout = string.Empty; - - if (context.Config.Options.TargetApi == TargetApi.Vulkan) - { - layout = $"layout (location = {32 + attr}) "; - } - + int location = context.Config.GetPerPatchAttributeLocation(attr); string name = $"{DefaultNames.PerPatchAttributePrefix}{attr}"; - context.AppendLine($"{layout}patch in vec4 {name};"); + context.AppendLine($"layout (location = {location}) patch in vec4 {name};"); } private static void DeclareOutputAttributes(CodeGenContext context, StructuredProgramInfo info) @@ -624,28 +625,20 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl } } - private static void DeclareUsedOutputAttributesPerPatch(CodeGenContext context, int usedAttributes) + private static void DeclareUsedOutputAttributesPerPatch(CodeGenContext context, HashSet<int> attrs) { - while (usedAttributes != 0) + foreach (int attr in attrs.OrderBy(x => x)) { - int index = BitOperations.TrailingZeroCount(usedAttributes); - DeclareOutputAttributePerPatch(context, index); - usedAttributes &= ~(1 << index); + DeclareOutputAttributePerPatch(context, attr); } } private static void DeclareOutputAttributePerPatch(CodeGenContext context, int attr) { - string layout = string.Empty; - - if (context.Config.Options.TargetApi == TargetApi.Vulkan) - { - layout = $"layout (location = {32 + attr}) "; - } - + int location = context.Config.GetPerPatchAttributeLocation(attr); string name = $"{DefaultNames.PerPatchAttributePrefix}{attr}"; - context.AppendLine($"{layout}patch out vec4 {name};"); + context.AppendLine($"layout (location = {location}) patch out vec4 {name};"); } private static void DeclareSupportUniformBlock(CodeGenContext context, ShaderStage stage, int scaleElements) diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs index 1ab91f77..fd284316 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs @@ -28,33 +28,27 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl private static Dictionary<int, BuiltInAttribute> _builtInAttributes = new Dictionary<int, BuiltInAttribute>() { - { AttributeConsts.TessLevelOuter0, new BuiltInAttribute("gl_TessLevelOuter[0]", VariableType.F32) }, - { AttributeConsts.TessLevelOuter1, new BuiltInAttribute("gl_TessLevelOuter[1]", VariableType.F32) }, - { AttributeConsts.TessLevelOuter2, new BuiltInAttribute("gl_TessLevelOuter[2]", VariableType.F32) }, - { AttributeConsts.TessLevelOuter3, new BuiltInAttribute("gl_TessLevelOuter[3]", VariableType.F32) }, - { AttributeConsts.TessLevelInner0, new BuiltInAttribute("gl_TessLevelInner[0]", VariableType.F32) }, - { AttributeConsts.TessLevelInner1, new BuiltInAttribute("gl_TessLevelInner[1]", VariableType.F32) }, - { AttributeConsts.Layer, new BuiltInAttribute("gl_Layer", VariableType.S32) }, - { AttributeConsts.PointSize, new BuiltInAttribute("gl_PointSize", VariableType.F32) }, - { AttributeConsts.PositionX, new BuiltInAttribute("gl_Position.x", VariableType.F32) }, - { AttributeConsts.PositionY, new BuiltInAttribute("gl_Position.y", VariableType.F32) }, - { AttributeConsts.PositionZ, new BuiltInAttribute("gl_Position.z", VariableType.F32) }, - { AttributeConsts.PositionW, new BuiltInAttribute("gl_Position.w", VariableType.F32) }, - { AttributeConsts.ClipDistance0, new BuiltInAttribute("gl_ClipDistance[0]", VariableType.F32) }, - { AttributeConsts.ClipDistance1, new BuiltInAttribute("gl_ClipDistance[1]", VariableType.F32) }, - { AttributeConsts.ClipDistance2, new BuiltInAttribute("gl_ClipDistance[2]", VariableType.F32) }, - { AttributeConsts.ClipDistance3, new BuiltInAttribute("gl_ClipDistance[3]", VariableType.F32) }, - { AttributeConsts.ClipDistance4, new BuiltInAttribute("gl_ClipDistance[4]", VariableType.F32) }, - { AttributeConsts.ClipDistance5, new BuiltInAttribute("gl_ClipDistance[5]", VariableType.F32) }, - { AttributeConsts.ClipDistance6, new BuiltInAttribute("gl_ClipDistance[6]", VariableType.F32) }, - { AttributeConsts.ClipDistance7, new BuiltInAttribute("gl_ClipDistance[7]", VariableType.F32) }, - { AttributeConsts.PointCoordX, new BuiltInAttribute("gl_PointCoord.x", VariableType.F32) }, - { AttributeConsts.PointCoordY, new BuiltInAttribute("gl_PointCoord.y", VariableType.F32) }, - { AttributeConsts.TessCoordX, new BuiltInAttribute("gl_TessCoord.x", VariableType.F32) }, - { AttributeConsts.TessCoordY, new BuiltInAttribute("gl_TessCoord.y", VariableType.F32) }, - { AttributeConsts.InstanceId, new BuiltInAttribute("gl_InstanceID", VariableType.S32) }, - { AttributeConsts.VertexId, new BuiltInAttribute("gl_VertexID", VariableType.S32) }, - { AttributeConsts.FrontFacing, new BuiltInAttribute("gl_FrontFacing", VariableType.Bool) }, + { AttributeConsts.Layer, new BuiltInAttribute("gl_Layer", VariableType.S32) }, + { AttributeConsts.PointSize, new BuiltInAttribute("gl_PointSize", VariableType.F32) }, + { AttributeConsts.PositionX, new BuiltInAttribute("gl_Position.x", VariableType.F32) }, + { AttributeConsts.PositionY, new BuiltInAttribute("gl_Position.y", VariableType.F32) }, + { AttributeConsts.PositionZ, new BuiltInAttribute("gl_Position.z", VariableType.F32) }, + { AttributeConsts.PositionW, new BuiltInAttribute("gl_Position.w", VariableType.F32) }, + { AttributeConsts.ClipDistance0, new BuiltInAttribute("gl_ClipDistance[0]", VariableType.F32) }, + { AttributeConsts.ClipDistance1, new BuiltInAttribute("gl_ClipDistance[1]", VariableType.F32) }, + { AttributeConsts.ClipDistance2, new BuiltInAttribute("gl_ClipDistance[2]", VariableType.F32) }, + { AttributeConsts.ClipDistance3, new BuiltInAttribute("gl_ClipDistance[3]", VariableType.F32) }, + { AttributeConsts.ClipDistance4, new BuiltInAttribute("gl_ClipDistance[4]", VariableType.F32) }, + { AttributeConsts.ClipDistance5, new BuiltInAttribute("gl_ClipDistance[5]", VariableType.F32) }, + { AttributeConsts.ClipDistance6, new BuiltInAttribute("gl_ClipDistance[6]", VariableType.F32) }, + { AttributeConsts.ClipDistance7, new BuiltInAttribute("gl_ClipDistance[7]", VariableType.F32) }, + { AttributeConsts.PointCoordX, new BuiltInAttribute("gl_PointCoord.x", VariableType.F32) }, + { AttributeConsts.PointCoordY, new BuiltInAttribute("gl_PointCoord.y", VariableType.F32) }, + { AttributeConsts.TessCoordX, new BuiltInAttribute("gl_TessCoord.x", VariableType.F32) }, + { AttributeConsts.TessCoordY, new BuiltInAttribute("gl_TessCoord.y", VariableType.F32) }, + { AttributeConsts.InstanceId, new BuiltInAttribute("gl_InstanceID", VariableType.S32) }, + { AttributeConsts.VertexId, new BuiltInAttribute("gl_VertexID", VariableType.S32) }, + { AttributeConsts.FrontFacing, new BuiltInAttribute("gl_FrontFacing", VariableType.Bool) }, // Special. { AttributeConsts.FragmentOutputDepth, new BuiltInAttribute("gl_FragDepth", VariableType.F32) }, @@ -170,7 +164,29 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl value &= AttributeConsts.Mask & ~3; char swzMask = GetSwizzleMask((value >> 2) & 3); - if (value >= AttributeConsts.UserAttributeBase && value < AttributeConsts.UserAttributeEnd) + if (perPatch) + { + if (value >= AttributeConsts.UserAttributePerPatchBase && value < AttributeConsts.UserAttributePerPatchEnd) + { + value -= AttributeConsts.UserAttributePerPatchBase; + + return $"{DefaultNames.PerPatchAttributePrefix}{(value >> 4)}.{swzMask}"; + } + else if (value < AttributeConsts.UserAttributePerPatchBase) + { + return value switch + { + AttributeConsts.TessLevelOuter0 => "gl_TessLevelOuter[0]", + AttributeConsts.TessLevelOuter1 => "gl_TessLevelOuter[1]", + AttributeConsts.TessLevelOuter2 => "gl_TessLevelOuter[2]", + AttributeConsts.TessLevelOuter3 => "gl_TessLevelOuter[3]", + AttributeConsts.TessLevelInner0 => "gl_TessLevelInner[0]", + AttributeConsts.TessLevelInner1 => "gl_TessLevelInner[1]", + _ => null + }; + } + } + else if (value >= AttributeConsts.UserAttributeBase && value < AttributeConsts.UserAttributeEnd) { value -= AttributeConsts.UserAttributeBase; @@ -180,11 +196,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl bool indexable = config.UsedFeatures.HasFlag(isOutAttr ? FeatureFlags.OaIndexing : FeatureFlags.IaIndexing); - if (!indexable && perPatch) - { - prefix = DefaultNames.PerPatchAttributePrefix; - } - if (indexable) { string name = prefix; @@ -202,7 +213,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl { string name = $"{prefix}{(value >> 4)}_{swzMask}"; - if (!perPatch && AttributeInfo.IsArrayAttributeGlsl(config.Stage, isOutAttr)) + if (AttributeInfo.IsArrayAttributeGlsl(config.Stage, isOutAttr)) { name += isOutAttr ? "[gl_InvocationID]" : $"[{indexExpr}]"; } @@ -213,7 +224,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl { string name = $"{prefix}{(value >> 4)}"; - if (!perPatch && AttributeInfo.IsArrayAttributeGlsl(config.Stage, isOutAttr)) + if (AttributeInfo.IsArrayAttributeGlsl(config.Stage, isOutAttr)) { name += isOutAttr ? "[gl_InvocationID]" : $"[{indexExpr}]"; } @@ -277,7 +288,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl string name = builtInAttr.Name; - if (!perPatch && AttributeInfo.IsArrayAttributeGlsl(config.Stage, isOutAttr) && AttributeInfo.IsArrayBuiltIn(value)) + if (AttributeInfo.IsArrayAttributeGlsl(config.Stage, isOutAttr) && AttributeInfo.IsArrayBuiltIn(value)) { name = isOutAttr ? $"gl_out[gl_InvocationID].{name}" : $"gl_in[{indexExpr}].{name}"; } diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs index d70a00ed..fe5e11f4 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs @@ -382,17 +382,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv public Instruction GetAttributePerPatchElemPointer(int attr, bool isOutAttr, out AggregateType elemType) { var storageClass = isOutAttr ? StorageClass.Output : StorageClass.Input; - var attrInfo = AttributeInfo.From(Config, attr, isOutAttr); + var attrInfo = AttributeInfo.FromPatch(Config, attr, isOutAttr); int attrOffset = attrInfo.BaseValue; - Instruction ioVariable; - - bool isUserAttr = attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd; + Instruction ioVariable = isOutAttr ? OutputsPerPatch[attrOffset] : InputsPerPatch[attrOffset]; elemType = attrInfo.Type & AggregateType.ElementTypeMask; - ioVariable = isOutAttr ? OutputsPerPatch[attrOffset] : InputsPerPatch[attrOffset]; - if ((attrInfo.Type & (AggregateType.Array | AggregateType.Vector)) == 0) { return ioVariable; @@ -404,7 +400,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv public Instruction GetAttributePerPatch(AggregateType type, int attr, bool isOutAttr) { - if (!AttributeInfo.Validate(Config, attr, isOutAttr: false)) + if (!AttributeInfo.ValidatePerPatch(Config, attr, isOutAttr: false)) { return GetConstant(type, new AstOperand(IrOperandType.Constant, 0)); } diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs index dce5e48a..1a4decf5 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs @@ -403,7 +403,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv foreach (int attr in inputs) { - if (!AttributeInfo.Validate(context.Config, attr, isOutAttr: false)) + if (!AttributeInfo.Validate(context.Config, attr, isOutAttr: false, perPatch)) { continue; } @@ -459,7 +459,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv foreach (int attr in outputs) { - if (!AttributeInfo.Validate(context.Config, attr, isOutAttr: true)) + if (!AttributeInfo.Validate(context.Config, attr, isOutAttr: true, perPatch)) { continue; } @@ -519,7 +519,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv ? (isOutAttr ? context.OutputsPerPatch : context.InputsPerPatch) : (isOutAttr ? context.Outputs : context.Inputs); - var attrInfo = AttributeInfo.From(context.Config, attr, isOutAttr); + var attrInfo = perPatch + ? AttributeInfo.FromPatch(context.Config, attr, isOutAttr) + : AttributeInfo.From(context.Config, attr, isOutAttr); if (dict.ContainsKey(attrInfo.BaseValue)) { @@ -544,11 +546,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv var spvType = context.TypePointer(storageClass, attrType); var spvVar = context.Variable(spvType, storageClass); - if (perPatch) - { - context.Decorate(spvVar, Decoration.Patch); - } - if (builtInPassthrough) { context.Decorate(spvVar, Decoration.PassthroughNV); @@ -556,6 +553,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv if (attrInfo.IsBuiltin) { + if (perPatch) + { + context.Decorate(spvVar, Decoration.Patch); + } + context.Decorate(spvVar, Decoration.BuiltIn, (LiteralInteger)GetBuiltIn(context, attrInfo.BaseValue)); if (context.Config.TransformFeedbackEnabled && context.Config.LastInVertexPipeline && isOutAttr) @@ -569,6 +571,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv } } } + else if (perPatch) + { + context.Decorate(spvVar, Decoration.Patch); + + int location = context.Config.GetPerPatchAttributeLocation((attr - AttributeConsts.UserAttributePerPatchBase) / 16); + + context.Decorate(spvVar, Decoration.Location, (LiteralInteger)location); + } else if (isUserAttr) { int location = (attr - AttributeConsts.UserAttributeBase) / 16; diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs index a7fb78b4..c743a274 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs @@ -882,7 +882,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv if (src2 is AstOperand operand && operand.Type == OperandType.Constant) { int attrOffset = (baseAttr.Value & AttributeConsts.Mask) + (operand.Value << 2); - return new OperationResult(resultType, context.GetAttribute(resultType, attrOffset, isOutAttr: false, index)); + bool isOutAttr = (baseAttr.Value & AttributeConsts.LoadOutputMask) != 0; + return new OperationResult(resultType, context.GetAttribute(resultType, attrOffset, isOutAttr, index)); } else { diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs index 23c6af81..fad7f9b8 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs @@ -191,7 +191,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv break; } - if (context.Config.GpuAccessor.QueryTessCw()) + bool tessCw = context.Config.GpuAccessor.QueryTessCw(); + + if (context.Config.Options.TargetApi == TargetApi.Vulkan) + { + // We invert the front face on Vulkan backend, so we need to do that here aswell. + tessCw = !tessCw; + } + + if (tessCw) { context.AddExecutionMode(spvFunc, ExecutionMode.VertexOrderCw); } @@ -375,9 +383,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv } else if (dest.Type == OperandType.Attribute || dest.Type == OperandType.AttributePerPatch) { - if (AttributeInfo.Validate(context.Config, dest.Value, isOutAttr: true)) + bool perPatch = dest.Type == OperandType.AttributePerPatch; + + if (AttributeInfo.Validate(context.Config, dest.Value, isOutAttr: true, perPatch)) { - bool perPatch = dest.Type == OperandType.AttributePerPatch; AggregateType elemType; var elemPointer = perPatch |