diff options
author | gdkchan <gab.dark.100@gmail.com> | 2021-11-08 13:18:46 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-08 13:18:46 -0300 |
commit | 911ea38e939459c652c6e27a28599340a61267dc (patch) | |
tree | e0e22a504b67f51625a7c23dd8157bada6841f77 /Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs | |
parent | 3dee712164e635fd3a0d2e9d359a7d11a80bf675 (diff) |
Support shader gl_Color, gl_SecondaryColor and gl_TexCoord built-ins (#2817)
* Support shader gl_Color, gl_SecondaryColor and gl_TexCoord built-ins
* Shader cache version bump
* Fix back color value on fragment shader
* Disable IPA multiplication for fixed function attributes and back color selection
Diffstat (limited to 'Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs')
-rw-r--r-- | Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs | 84 |
1 files changed, 80 insertions, 4 deletions
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs index f82b835c..e2131602 100644 --- a/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs +++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs @@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.Shader.Instructions } else if (op.SrcB == RegisterConsts.RegisterZeroIndex || op.P) { - int offset = op.Imm11 + index * 4; + int offset = FixedFuncToUserAttribute(context.Config, op.Imm11 + index * 4, op.O); context.FlagAttributeRead(offset); @@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Shader.Instructions } else { - int offset = op.Imm11 + index * 4; + int offset = FixedFuncToUserAttribute(context.Config, op.Imm11 + index * 4, op.O); context.FlagAttributeRead(offset); @@ -101,6 +101,13 @@ namespace Ryujinx.Graphics.Shader.Instructions int offset = op.Imm11 + index * 4; + if (!context.Config.IsUsedOutputAttribute(offset)) + { + return; + } + + offset = FixedFuncToUserAttribute(context.Config, offset, isOutput: true); + context.FlagAttributeWritten(offset); Operand dest = op.P ? AttributePerPatch(offset) : Attribute(offset); @@ -118,6 +125,8 @@ namespace Ryujinx.Graphics.Shader.Instructions Operand res; + bool isFixedFunc = false; + if (op.Idx) { Operand userAttrOffset = context.ISubtract(GetSrcReg(context, op.SrcA), Const(AttributeConsts.UserAttributeBase)); @@ -130,7 +139,7 @@ namespace Ryujinx.Graphics.Shader.Instructions } else { - res = Attribute(op.Imm10); + isFixedFunc = TryFixedFuncToUserAttributeIpa(context, op.Imm10, out res); if (op.Imm10 >= AttributeConsts.UserAttributeBase && op.Imm10 < AttributeConsts.UserAttributeEnd) { @@ -143,7 +152,7 @@ namespace Ryujinx.Graphics.Shader.Instructions } } - if (op.IpaOp == IpaOp.Multiply) + if (op.IpaOp == IpaOp.Multiply && !isFixedFunc) { Operand srcB = GetSrcReg(context, op.SrcB); @@ -204,5 +213,72 @@ namespace Ryujinx.Graphics.Shader.Instructions context.EndPrimitive(); } } + + private static bool TryFixedFuncToUserAttributeIpa(EmitterContext context, int attr, out Operand selectedAttr) + { + if (attr >= AttributeConsts.FrontColorDiffuseR && attr < AttributeConsts.BackColorDiffuseR) + { + // TODO: If two sided rendering is enabled, then this should return + // FrontColor if the fragment is front facing, and back color otherwise. + int index = (attr - AttributeConsts.FrontColorDiffuseR) >> 4; + int userAttrIndex = context.Config.GetFreeUserAttribute(isOutput: false, index); + Operand frontAttr = Attribute(AttributeConsts.UserAttributeBase + userAttrIndex * 16 + (attr & 0xf)); + + context.Config.SetInputUserAttributeFixedFunc(userAttrIndex); + + selectedAttr = frontAttr; + return true; + } + else if (attr >= AttributeConsts.BackColorDiffuseR && attr < AttributeConsts.ClipDistance0) + { + selectedAttr = ConstF(((attr >> 2) & 3) == 3 ? 1f : 0f); + return true; + } + else if (attr >= AttributeConsts.TexCoordBase && attr < AttributeConsts.TexCoordEnd) + { + selectedAttr = Attribute(FixedFuncToUserAttribute(context.Config, attr, AttributeConsts.TexCoordBase, 4, isOutput: false)); + return true; + } + + selectedAttr = Attribute(attr); + return false; + } + + private static int FixedFuncToUserAttribute(ShaderConfig config, int attr, bool isOutput) + { + if (attr >= AttributeConsts.FrontColorDiffuseR && attr < AttributeConsts.ClipDistance0) + { + attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.FrontColorDiffuseR, 0, isOutput); + } + else if (attr >= AttributeConsts.TexCoordBase && attr < AttributeConsts.TexCoordEnd) + { + attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.TexCoordBase, 4, isOutput); + } + + return attr; + } + + private static int FixedFuncToUserAttribute(ShaderConfig config, int attr, int baseAttr, int baseIndex, bool isOutput) + { + int index = (attr - baseAttr) >> 4; + int userAttrIndex = config.GetFreeUserAttribute(isOutput, index); + + if ((uint)userAttrIndex < Constants.MaxAttributes) + { + userAttrIndex += baseIndex; + attr = AttributeConsts.UserAttributeBase + userAttrIndex * 16 + (attr & 0xf); + + if (isOutput) + { + config.SetOutputUserAttributeFixedFunc(userAttrIndex); + } + else + { + config.SetInputUserAttributeFixedFunc(userAttrIndex); + } + } + + return attr; + } } }
\ No newline at end of file |