aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Instructions
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2021-08-26 20:44:47 -0300
committerGitHub <noreply@github.com>2021-08-27 01:44:47 +0200
commitee1038e54255797a94b89091f4d59b77daad1a7b (patch)
tree5ea62d8a2bae97004a4abe2ebf0a21c634b912dc /Ryujinx.Graphics.Shader/Instructions
parentec3e848d7998038ce22c41acdbf81032bf47991f (diff)
Initial support for shader attribute indexing (#2546)
* Initial support for shader attribute indexing * Support output indexing too, other improvements * Fix order * Address feedback
Diffstat (limited to 'Ryujinx.Graphics.Shader/Instructions')
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs83
1 files changed, 71 insertions, 12 deletions
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
index 7afdbf4e..6744a9e8 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
@@ -15,6 +15,18 @@ namespace Ryujinx.Graphics.Shader.Instructions
Shared
}
+ public static void Al2p(EmitterContext context)
+ {
+ OpCodeAl2p op = (OpCodeAl2p)context.CurrOp;
+
+ if (op.Rd.IsRZ)
+ {
+ return;
+ }
+
+ context.Copy(Register(op.Rd), context.IAdd(Register(op.Ra), Const(op.Immediate)));
+ }
+
public static void Ald(EmitterContext context)
{
OpCodeAttribute op = (OpCodeAttribute)context.CurrOp;
@@ -30,11 +42,31 @@ namespace Ryujinx.Graphics.Shader.Instructions
break;
}
- Operand src = Attribute(op.AttributeOffset + index * 4);
+ if (op.Phys)
+ {
+ Operand userAttrOffset = context.ISubtract(GetSrcA(context), Const(AttributeConsts.UserAttributeBase));
+ Operand userAttrIndex = context.ShiftRightU32(userAttrOffset, Const(2));
+
+ context.Copy(Register(rd), context.LoadAttribute(Const(AttributeConsts.UserAttributeBase), userAttrIndex, primVertex));
+
+ context.Config.SetUsedFeature(FeatureFlags.IaIndexing);
+ }
+ else if (op.Rc.IsRZ)
+ {
+ Operand src = Attribute(op.AttributeOffset + index * 4);
+
+ context.FlagAttributeRead(src.Value);
+
+ context.Copy(Register(rd), src);
+ }
+ else
+ {
+ Operand src = Const(op.AttributeOffset + index * 4);
- context.FlagAttributeRead(src.Value);
+ context.FlagAttributeRead(src.Value);
- context.Copy(Register(rd), context.LoadAttribute(src, primVertex));
+ context.Copy(Register(rd), context.LoadAttribute(src, Const(0), primVertex));
+ }
}
}
@@ -51,11 +83,23 @@ namespace Ryujinx.Graphics.Shader.Instructions
Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);
- Operand dest = Attribute(op.AttributeOffset + index * 4);
+ if (op.Phys)
+ {
+ Operand userAttrOffset = context.ISubtract(GetSrcA(context), Const(AttributeConsts.UserAttributeBase));
+ Operand userAttrIndex = context.ShiftRightU32(userAttrOffset, Const(2));
+
+ context.StoreAttribute(Const(AttributeConsts.UserAttributeBase), userAttrIndex, Register(rd));
+
+ context.Config.SetUsedFeature(FeatureFlags.OaIndexing);
+ }
+ else
+ {
+ Operand dest = Attribute(op.AttributeOffset + index * 4);
- context.FlagAttributeWritten(dest.Value);
+ context.FlagAttributeWritten(dest.Value);
- context.Copy(dest, Register(rd));
+ context.Copy(dest, Register(rd));
+ }
}
}
@@ -136,16 +180,31 @@ namespace Ryujinx.Graphics.Shader.Instructions
context.FlagAttributeRead(op.AttributeOffset);
- Operand res = Attribute(op.AttributeOffset);
+ Operand res;
- if (op.AttributeOffset >= AttributeConsts.UserAttributeBase &&
- op.AttributeOffset < AttributeConsts.UserAttributeEnd)
+ if (op.Idx)
{
- int index = (op.AttributeOffset - AttributeConsts.UserAttributeBase) >> 4;
+ Operand userAttrOffset = context.ISubtract(GetSrcA(context), Const(AttributeConsts.UserAttributeBase));
+ Operand userAttrIndex = context.ShiftRightU32(userAttrOffset, Const(2));
+
+ res = context.LoadAttribute(Const(AttributeConsts.UserAttributeBase), userAttrIndex, Const(0));
+ res = context.FPMultiply(res, Attribute(AttributeConsts.PositionW));
- if (context.Config.ImapTypes[index].GetFirstUsedType() == PixelImap.Perspective)
+ context.Config.SetUsedFeature(FeatureFlags.IaIndexing);
+ }
+ else
+ {
+ res = Attribute(op.AttributeOffset);
+
+ if (op.AttributeOffset >= AttributeConsts.UserAttributeBase &&
+ op.AttributeOffset < AttributeConsts.UserAttributeEnd)
{
- res = context.FPMultiply(res, Attribute(AttributeConsts.PositionW));
+ int index = (op.AttributeOffset - AttributeConsts.UserAttributeBase) >> 4;
+
+ if (context.Config.ImapTypes[index].GetFirstUsedType() == PixelImap.Perspective)
+ {
+ res = context.FPMultiply(res, Attribute(AttributeConsts.PositionW));
+ }
}
}