diff options
author | gdkchan <gab.dark.100@gmail.com> | 2023-04-25 19:51:07 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-25 19:51:07 -0300 |
commit | 9f12e50a546b15533778ed0d8290202af91c10a2 (patch) | |
tree | f0e77a7b7c605face5ef29270b4248af2682301a /Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs | |
parent | 097562bc6c227c42f803ce1078fcb4adf06cd20c (diff) |
Refactor attribute handling on the shader generator (#4565)1.1.733
* Refactor attribute handling on the shader generator
* Implement gl_ViewportMask[]
* Add back the Intel FrontFacing bug workaround
* Fix GLSL transform feedback outputs mistmatch with fragment stage
* Shader cache version bump
* Fix geometry shader recognition
* PR feedback
* Delete GetOperandDef and GetOperandUse
* Remove replacements that are no longer needed on GLSL compilation on Vulkan
* Fix incorrect load for per-patch outputs
* Fix build
Diffstat (limited to 'Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs')
-rw-r--r-- | Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs | 255 |
1 files changed, 4 insertions, 251 deletions
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs index e693307d..ed292ef1 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs @@ -29,15 +29,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv public Instruction StorageBuffersArray { get; set; } public Instruction LocalMemory { get; set; } public Instruction SharedMemory { get; set; } - public Instruction InputsArray { get; set; } - public Instruction OutputsArray { get; set; } public Dictionary<TextureMeta, SamplerType> SamplersTypes { get; } = new Dictionary<TextureMeta, SamplerType>(); public Dictionary<TextureMeta, (Instruction, Instruction, Instruction)> Samplers { get; } = new Dictionary<TextureMeta, (Instruction, Instruction, Instruction)>(); public Dictionary<TextureMeta, (Instruction, Instruction)> Images { get; } = new Dictionary<TextureMeta, (Instruction, Instruction)>(); - public Dictionary<int, Instruction> Inputs { get; } = new Dictionary<int, Instruction>(); - public Dictionary<int, Instruction> Outputs { get; } = new Dictionary<int, Instruction>(); - public Dictionary<int, Instruction> InputsPerPatch { get; } = new Dictionary<int, Instruction>(); - public Dictionary<int, Instruction> OutputsPerPatch { get; } = new Dictionary<int, Instruction>(); + public Dictionary<IoDefinition, Instruction> Inputs { get; } = new Dictionary<IoDefinition, Instruction>(); + public Dictionary<IoDefinition, Instruction> Outputs { get; } = new Dictionary<IoDefinition, Instruction>(); + public Dictionary<IoDefinition, Instruction> InputsPerPatch { get; } = new Dictionary<IoDefinition, Instruction>(); + public Dictionary<IoDefinition, Instruction> OutputsPerPatch { get; } = new Dictionary<IoDefinition, Instruction>(); public Instruction CoordTemp { get; set; } private readonly Dictionary<AstOperand, Instruction> _locals = new Dictionary<AstOperand, Instruction>(); @@ -163,16 +161,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv mainInterface.AddRange(InputsPerPatch.Values); mainInterface.AddRange(OutputsPerPatch.Values); - if (InputsArray != null) - { - mainInterface.Add(InputsArray); - } - - if (OutputsArray != null) - { - mainInterface.Add(OutputsArray); - } - return mainInterface.ToArray(); } @@ -228,8 +216,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv return operand.Type switch { IrOperandType.Argument => GetArgument(type, operand), - IrOperandType.Attribute => GetAttribute(type, operand.Value & AttributeConsts.Mask, (operand.Value & AttributeConsts.LoadOutputMask) != 0), - IrOperandType.AttributePerPatch => GetAttributePerPatch(type, operand.Value & AttributeConsts.Mask, (operand.Value & AttributeConsts.LoadOutputMask) != 0), IrOperandType.Constant => GetConstant(type, operand), IrOperandType.ConstantBuffer => GetConstantBuffer(type, operand), IrOperandType.LocalVariable => GetLocal(type, operand), @@ -275,239 +261,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv }; } - public Instruction GetAttributeElemPointer(int attr, bool isOutAttr, Instruction index, out AggregateType elemType) - { - var storageClass = isOutAttr ? StorageClass.Output : StorageClass.Input; - var attrInfo = AttributeInfo.From(Config, attr, isOutAttr); - - int attrOffset = attrInfo.BaseValue; - AggregateType type = attrInfo.Type; - - Instruction ioVariable, elemIndex; - - Instruction invocationId = null; - - if (Config.Stage == ShaderStage.TessellationControl && isOutAttr) - { - invocationId = Load(TypeS32(), Inputs[AttributeConsts.InvocationId]); - } - - bool isUserAttr = attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd; - - if (isUserAttr && - ((!isOutAttr && Config.UsedFeatures.HasFlag(FeatureFlags.IaIndexing)) || - (isOutAttr && Config.UsedFeatures.HasFlag(FeatureFlags.OaIndexing)))) - { - elemType = AggregateType.FP32; - ioVariable = isOutAttr ? OutputsArray : InputsArray; - elemIndex = Constant(TypeU32(), attrInfo.GetInnermostIndex()); - var vecIndex = Constant(TypeU32(), (attr - AttributeConsts.UserAttributeBase) >> 4); - - bool isArray = AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr); - - if (invocationId != null && isArray) - { - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, index, vecIndex, elemIndex); - } - else if (invocationId != null) - { - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, vecIndex, elemIndex); - } - else if (isArray) - { - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, vecIndex, elemIndex); - } - else - { - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, vecIndex, elemIndex); - } - } - - bool isViewportInverse = attr == AttributeConsts.SupportBlockViewInverseX || attr == AttributeConsts.SupportBlockViewInverseY; - - if (isViewportInverse) - { - elemType = AggregateType.FP32; - elemIndex = Constant(TypeU32(), (attr - AttributeConsts.SupportBlockViewInverseX) >> 2); - return AccessChain(TypePointer(StorageClass.Uniform, TypeFP32()), SupportBuffer, Constant(TypeU32(), 2), elemIndex); - } - - elemType = attrInfo.Type & AggregateType.ElementTypeMask; - - if (isUserAttr && Config.TransformFeedbackEnabled && - ((isOutAttr && Config.LastInVertexPipeline) || - (!isOutAttr && Config.Stage == ShaderStage.Fragment))) - { - attrOffset = attr; - type = elemType; - - if (isOutAttr) - { - int components = Info.GetTransformFeedbackOutputComponents(attr); - - if (components > 1) - { - attrOffset &= ~0xf; - type = components switch - { - 2 => AggregateType.Vector2 | AggregateType.FP32, - 3 => AggregateType.Vector3 | AggregateType.FP32, - 4 => AggregateType.Vector4 | AggregateType.FP32, - _ => AggregateType.FP32 - }; - - attrInfo = new AttributeInfo(attrOffset, (attr - attrOffset) / 4, components, type, false); - } - } - } - - ioVariable = isOutAttr ? Outputs[attrOffset] : Inputs[attrOffset]; - - bool isIndexed = AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr) && (!attrInfo.IsBuiltin || AttributeInfo.IsArrayBuiltIn(attr)); - - if ((type & (AggregateType.Array | AggregateType.ElementCountMask)) == 0) - { - if (invocationId != null) - { - return isIndexed - ? AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, index) - : AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId); - } - else - { - return isIndexed ? AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index) : ioVariable; - } - } - - elemIndex = Constant(TypeU32(), attrInfo.GetInnermostIndex()); - - if (invocationId != null && isIndexed) - { - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, index, elemIndex); - } - else if (invocationId != null) - { - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, elemIndex); - } - else if (isIndexed) - { - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, elemIndex); - } - else - { - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, elemIndex); - } - } - - public Instruction GetAttributeElemPointer(Instruction attrIndex, bool isOutAttr, Instruction index, out AggregateType elemType) - { - var storageClass = isOutAttr ? StorageClass.Output : StorageClass.Input; - - Instruction invocationId = null; - - if (Config.Stage == ShaderStage.TessellationControl && isOutAttr) - { - invocationId = Load(TypeS32(), Inputs[AttributeConsts.InvocationId]); - } - - elemType = AggregateType.FP32; - var ioVariable = isOutAttr ? OutputsArray : InputsArray; - var vecIndex = ShiftRightLogical(TypeS32(), attrIndex, Constant(TypeS32(), 2)); - var elemIndex = BitwiseAnd(TypeS32(), attrIndex, Constant(TypeS32(), 3)); - - bool isArray = AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr); - - if (invocationId != null && isArray) - { - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, index, vecIndex, elemIndex); - } - else if (invocationId != null) - { - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, vecIndex, elemIndex); - } - else if (isArray) - { - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, vecIndex, elemIndex); - } - else - { - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, vecIndex, elemIndex); - } - } - - public Instruction GetAttribute(AggregateType type, int attr, bool isOutAttr, Instruction index = null) - { - if (!AttributeInfo.Validate(Config, attr, isOutAttr: false)) - { - return GetConstant(type, new AstOperand(IrOperandType.Constant, 0)); - } - - var elemPointer = GetAttributeElemPointer(attr, isOutAttr, index, out var elemType); - var value = Load(GetType(elemType), elemPointer); - - if (Config.Stage == ShaderStage.Fragment) - { - if (attr == AttributeConsts.PositionX || attr == AttributeConsts.PositionY) - { - var pointerType = TypePointer(StorageClass.Uniform, TypeFP32()); - var fieldIndex = Constant(TypeU32(), 4); - var scaleIndex = Constant(TypeU32(), 0); - - var scaleElemPointer = AccessChain(pointerType, SupportBuffer, fieldIndex, scaleIndex); - var scale = Load(TypeFP32(), scaleElemPointer); - - value = FDiv(TypeFP32(), value, scale); - } - else if (attr == AttributeConsts.FrontFacing && Config.GpuAccessor.QueryHostHasFrontFacingBug()) - { - // Workaround for what appears to be a bug on Intel compiler. - var valueFloat = Select(TypeFP32(), value, Constant(TypeFP32(), 1f), Constant(TypeFP32(), 0f)); - var valueAsInt = Bitcast(TypeS32(), valueFloat); - var valueNegated = SNegate(TypeS32(), valueAsInt); - - value = SLessThan(TypeBool(), valueNegated, Constant(TypeS32(), 0)); - } - } - - return BitcastIfNeeded(type, elemType, value); - } - - public Instruction GetAttributePerPatchElemPointer(int attr, bool isOutAttr, out AggregateType elemType) - { - var storageClass = isOutAttr ? StorageClass.Output : StorageClass.Input; - var attrInfo = AttributeInfo.FromPatch(Config, attr, isOutAttr); - - int attrOffset = attrInfo.BaseValue; - Instruction ioVariable = isOutAttr ? OutputsPerPatch[attrOffset] : InputsPerPatch[attrOffset]; - - elemType = attrInfo.Type & AggregateType.ElementTypeMask; - - if ((attrInfo.Type & (AggregateType.Array | AggregateType.ElementCountMask)) == 0) - { - return ioVariable; - } - - var elemIndex = Constant(TypeU32(), attrInfo.GetInnermostIndex()); - return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, elemIndex); - } - - public Instruction GetAttributePerPatch(AggregateType type, int attr, bool isOutAttr) - { - if (!AttributeInfo.ValidatePerPatch(Config, attr, isOutAttr: false)) - { - return GetConstant(type, new AstOperand(IrOperandType.Constant, 0)); - } - - var elemPointer = GetAttributePerPatchElemPointer(attr, isOutAttr, out var elemType); - return BitcastIfNeeded(type, elemType, Load(GetType(elemType), elemPointer)); - } - - public Instruction GetAttribute(AggregateType type, Instruction attr, bool isOutAttr, Instruction index = null) - { - var elemPointer = GetAttributeElemPointer(attr, isOutAttr, index, out var elemType); - return BitcastIfNeeded(type, elemType, Load(GetType(elemType), elemPointer)); - } - public Instruction GetConstant(AggregateType type, AstOperand operand) { return type switch |