aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2023-01-21 12:18:05 -0300
committerGitHub <noreply@github.com>2023-01-21 12:18:05 -0300
commit6adf15e479b684cad7a783e7a1a056be087fdc02 (patch)
tree857c8b14af4e49c2aa939b1496d7f53f304247bb
parent2747f125918951673b298964889276ded5de935d (diff)
Implement CSET and CSETP shader instructions (#4318)1.1.583
* Implement CSET and CSETP shader instructions * Shader cache version bump * Fix CC.HI
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs2
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs1
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmit.cs7
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitConditionCode.cs87
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs18
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerComparison.cs17
6 files changed, 90 insertions, 42 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
index 2622ea3e..9f436502 100644
--- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
- private const uint CodeGenVersion = 3939;
+ private const uint CodeGenVersion = 4318;
private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data";
diff --git a/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs b/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
index 98a43640..0c22ddc0 100644
--- a/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
@@ -91,6 +91,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
Neu = 13,
Geu = 14,
T = 15,
+ Off = 16,
Lo = 17,
Sff = 18,
Ls = 19,
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmit.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmit.cs
index c242963a..3a9e658a 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmit.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmit.cs
@@ -54,13 +54,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
context.Config.GpuAccessor.Log("Shader instruction Cctlt is not implemented.");
}
- public static void Cset(EmitterContext context)
- {
- InstCset op = context.GetOp<InstCset>();
-
- context.Config.GpuAccessor.Log("Shader instruction Cset is not implemented.");
- }
-
public static void Cs2r(EmitterContext context)
{
InstCs2r op = context.GetOp<InstCs2r>();
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitConditionCode.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitConditionCode.cs
new file mode 100644
index 00000000..74ac7602
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitConditionCode.cs
@@ -0,0 +1,87 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+ static partial class InstEmit
+ {
+ public static void Cset(EmitterContext context)
+ {
+ InstCset op = context.GetOp<InstCset>();
+
+ Operand res = GetCondition(context, op.Ccc);
+ Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
+
+ res = GetPredLogicalOp(context, op.Bop, res, srcPred);
+
+ Operand dest = GetDest(op.Dest);
+
+ if (op.BVal)
+ {
+ context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0)));
+ }
+ else
+ {
+ context.Copy(dest, res);
+ }
+
+ // TODO: CC.
+ }
+
+ public static void Csetp(EmitterContext context)
+ {
+ InstCsetp op = context.GetOp<InstCsetp>();
+
+ Operand p0Res = GetCondition(context, op.Ccc);
+ Operand p1Res = context.BitwiseNot(p0Res);
+ Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
+
+ p0Res = GetPredLogicalOp(context, op.Bop, p0Res, srcPred);
+ p1Res = GetPredLogicalOp(context, op.Bop, p1Res, srcPred);
+
+ context.Copy(Register(op.DestPred, RegisterType.Predicate), p0Res);
+ context.Copy(Register(op.DestPredInv, RegisterType.Predicate), p1Res);
+
+ // TODO: CC.
+ }
+
+ private static Operand GetCondition(EmitterContext context, Ccc cond, int defaultCond = IrConsts.True)
+ {
+ return cond switch
+ {
+ Ccc.F => Const(IrConsts.False),
+ Ccc.Lt => context.BitwiseExclusiveOr(context.BitwiseAnd(GetNF(), context.BitwiseNot(GetZF())), GetVF()),
+ Ccc.Eq => context.BitwiseAnd(context.BitwiseNot(GetNF()), GetZF()),
+ Ccc.Le => context.BitwiseExclusiveOr(GetNF(), context.BitwiseOr(GetZF(), GetVF())),
+ Ccc.Gt => context.BitwiseNot(context.BitwiseOr(context.BitwiseExclusiveOr(GetNF(), GetVF()), GetZF())),
+ Ccc.Ne => context.BitwiseNot(GetZF()),
+ Ccc.Ge => context.BitwiseNot(context.BitwiseExclusiveOr(GetNF(), GetVF())),
+ Ccc.Num => context.BitwiseNot(context.BitwiseAnd(GetNF(), GetZF())),
+ Ccc.Nan => context.BitwiseAnd(GetNF(), GetZF()),
+ Ccc.Ltu => context.BitwiseExclusiveOr(GetNF(), GetVF()),
+ Ccc.Equ => GetZF(),
+ Ccc.Leu => context.BitwiseOr(context.BitwiseExclusiveOr(GetNF(), GetVF()), GetZF()),
+ Ccc.Gtu => context.BitwiseExclusiveOr(context.BitwiseNot(GetNF()), context.BitwiseOr(GetVF(), GetZF())),
+ Ccc.Neu => context.BitwiseOr(GetNF(), context.BitwiseNot(GetZF())),
+ Ccc.Geu => context.BitwiseExclusiveOr(context.BitwiseOr(context.BitwiseNot(GetNF()), GetZF()), GetVF()),
+ Ccc.T => Const(IrConsts.True),
+ Ccc.Off => context.BitwiseNot(GetVF()),
+ Ccc.Lo => context.BitwiseNot(GetCF()),
+ Ccc.Sff => context.BitwiseNot(GetNF()),
+ Ccc.Ls => context.BitwiseOr(GetZF(), context.BitwiseNot(GetCF())),
+ Ccc.Hi => context.BitwiseAnd(GetCF(), context.BitwiseNot(GetZF())),
+ Ccc.Sft => GetNF(),
+ Ccc.Hs => GetCF(),
+ Ccc.Oft => GetVF(),
+ Ccc.Rle => context.BitwiseOr(GetNF(), GetZF()),
+ Ccc.Rgt => context.BitwiseNot(context.BitwiseOr(GetNF(), GetZF())),
+ _ => Const(defaultCond)
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs
index f1dd279c..91c23230 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs
@@ -257,7 +257,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
else
{
- // TODO: Support CC here aswell (condition).
+ // TODO: Support CC here as well (condition).
foreach (SyncTarget target in targets.Values)
{
PushOpInfo pushOpInfo = target.PushOpInfo;
@@ -318,21 +318,5 @@ namespace Ryujinx.Graphics.Shader.Instructions
context.BranchIfTrue(label, pred);
}
}
-
- private static Operand GetCondition(EmitterContext context, Ccc cond, int defaultCond = IrConsts.True)
- {
- // TODO: More condition codes, figure out how they work.
- switch (cond)
- {
- case Ccc.Eq:
- case Ccc.Equ:
- return GetZF();
- case Ccc.Ne:
- case Ccc.Neu:
- return context.BitwiseNot(GetZF());
- }
-
- return Const(defaultCond);
- }
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerComparison.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerComparison.cs
index ddd90f8e..dcdb189f 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerComparison.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerComparison.cs
@@ -11,23 +11,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
static partial class InstEmit
{
- public static void Csetp(EmitterContext context)
- {
- InstCsetp op = context.GetOp<InstCsetp>();
-
- // TODO: Implement that properly.
-
- Operand p0Res = Const(IrConsts.True);
- Operand p1Res = context.BitwiseNot(p0Res);
- Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
-
- p0Res = GetPredLogicalOp(context, op.Bop, p0Res, srcPred);
- p1Res = GetPredLogicalOp(context, op.Bop, p1Res, srcPred);
-
- context.Copy(Register(op.DestPred, RegisterType.Predicate), p0Res);
- context.Copy(Register(op.DestPredInv, RegisterType.Predicate), p1Res);
- }
-
public static void IcmpR(EmitterContext context)
{
InstIcmpR op = context.GetOp<InstIcmpR>();