aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Instructions
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-01-10 12:08:00 -0300
committerGitHub <noreply@github.com>2022-01-10 12:08:00 -0300
commit7f6b3d234a0dd82866e89930f05c520aca94946e (patch)
tree49459142740eed719d431d9dc9ae37b0ff472ee8 /Ryujinx.Graphics.Shader/Instructions
parent952c6e4d454082da900a447e6bd1deb272c150c2 (diff)
Implement IMUL, PCNT and CONT shader instructions, fix FFMA32I and HFMA32I (#2972)
* Implement IMUL shader instruction * Implement PCNT/CONT instruction and fix FFMA32I * Add HFMA232I to the table * Shader cache version bump * No Rc on Ffma32i
Diffstat (limited to 'Ryujinx.Graphics.Shader/Instructions')
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmit.cs44
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitFloatArithmetic.cs6
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs26
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs47
4 files changed, 69 insertions, 54 deletions
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmit.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmit.cs
index b0cb7028..c242963a 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmit.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmit.cs
@@ -54,18 +54,11 @@ namespace Ryujinx.Graphics.Shader.Instructions
context.Config.GpuAccessor.Log("Shader instruction Cctlt is not implemented.");
}
- public static void Cont(EmitterContext context)
- {
- InstCont op = context.GetOp<InstCont>();
-
- context.Config.GpuAccessor.Log("Shader instruction ContUnsup is not implemented.");
- }
-
public static void Cset(EmitterContext context)
{
InstCset op = context.GetOp<InstCset>();
- context.Config.GpuAccessor.Log("Shader instruction CsetUnsup is not implemented.");
+ context.Config.GpuAccessor.Log("Shader instruction Cset is not implemented.");
}
public static void Cs2r(EmitterContext context)
@@ -159,34 +152,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
context.Config.GpuAccessor.Log("Shader instruction ImadspRc is not implemented.");
}
- public static void ImulR(EmitterContext context)
- {
- InstImulR op = context.GetOp<InstImulR>();
-
- context.Config.GpuAccessor.Log("Shader instruction ImulR is not implemented.");
- }
-
- public static void ImulI(EmitterContext context)
- {
- InstImulI op = context.GetOp<InstImulI>();
-
- context.Config.GpuAccessor.Log("Shader instruction ImulI is not implemented.");
- }
-
- public static void ImulC(EmitterContext context)
- {
- InstImulC op = context.GetOp<InstImulC>();
-
- context.Config.GpuAccessor.Log("Shader instruction ImulC is not implemented.");
- }
-
- public static void Imul32i(EmitterContext context)
- {
- InstImul32i op = context.GetOp<InstImul32i>();
-
- context.Config.GpuAccessor.Log("Shader instruction Imul32i is not implemented.");
- }
-
public static void Jcal(EmitterContext context)
{
InstJcal op = context.GetOp<InstJcal>();
@@ -250,13 +215,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
context.Config.GpuAccessor.Log("Shader instruction P2rC is not implemented.");
}
- public static void Pcnt(EmitterContext context)
- {
- InstPcnt op = context.GetOp<InstPcnt>();
-
- context.Config.GpuAccessor.Log("Shader instruction Pcnt is not implemented.");
- }
-
public static void Pexit(EmitterContext context)
{
InstPexit op = context.GetOp<InstPexit>();
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatArithmetic.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatArithmetic.cs
index 11d724c4..29803c31 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatArithmetic.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatArithmetic.cs
@@ -204,7 +204,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
var srcA = GetSrcReg(context, op.SrcA);
var srcB = GetSrcImm(context, op.Imm32);
- var srcC = GetSrcReg(context, op.SrcC);
+ var srcC = GetSrcReg(context, op.Dest);
EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
}
@@ -333,13 +333,13 @@ namespace Ryujinx.Graphics.Shader.Instructions
EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
}
- public static void Hfma232iI(EmitterContext context)
+ public static void Hfma232i(EmitterContext context)
{
InstHfma232i op = context.GetOp<InstHfma232i>();
var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
var srcB = GetHalfSrc(context, op.Imm);
- var srcC = GetHalfSrc(context, HalfSwizzle.F16, op.SrcC, op.NegC, false);
+ var srcC = GetHalfSrc(context, HalfSwizzle.F16, op.Dest, op.NegC, false);
EmitHfma2(context, OFmt.F16, srcA, srcB, srcC, op.Dest, saturate: false);
}
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs
index da34c1be..3cb8fe72 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
InstBrk op = context.GetOp<InstBrk>();
- EmitBrkOrSync(context);
+ EmitBrkContSync(context);
}
public static void Brx(EmitterContext context)
@@ -87,6 +87,13 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
}
+ public static void Cont(EmitterContext context)
+ {
+ InstCont op = context.GetOp<InstCont>();
+
+ EmitBrkContSync(context);
+ }
+
public static void Exit(EmitterContext context)
{
InstExit op = context.GetOp<InstExit>();
@@ -116,7 +123,14 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
InstPbk op = context.GetOp<InstPbk>();
- EmitPbkOrSsy(context);
+ EmitPbkPcntSsy(context);
+ }
+
+ public static void Pcnt(EmitterContext context)
+ {
+ InstPcnt op = context.GetOp<InstPcnt>();
+
+ EmitPbkPcntSsy(context);
}
public static void Ret(EmitterContext context)
@@ -137,17 +151,17 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
InstSsy op = context.GetOp<InstSsy>();
- EmitPbkOrSsy(context);
+ EmitPbkPcntSsy(context);
}
public static void Sync(EmitterContext context)
{
InstSync op = context.GetOp<InstSync>();
- EmitBrkOrSync(context);
+ EmitBrkContSync(context);
}
- private static void EmitPbkOrSsy(EmitterContext context)
+ private static void EmitPbkPcntSsy(EmitterContext context)
{
var consumers = context.CurrBlock.PushOpCodes.First(x => x.Op.Address == context.CurrOp.Address).Consumers;
@@ -162,7 +176,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
}
- private static void EmitBrkOrSync(EmitterContext context)
+ private static void EmitBrkContSync(EmitterContext context)
{
var targets = context.CurrBlock.SyncTargets;
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs
index ac8cca1b..374e3d61 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs
@@ -138,6 +138,46 @@ namespace Ryujinx.Graphics.Shader.Instructions
EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
}
+ public static void ImulR(EmitterContext context)
+ {
+ InstImulR op = context.GetOp<InstImulR>();
+
+ var srcA = GetSrcReg(context, op.SrcA);
+ var srcB = GetSrcReg(context, op.SrcB);
+
+ EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo);
+ }
+
+ public static void ImulI(EmitterContext context)
+ {
+ InstImulI op = context.GetOp<InstImulI>();
+
+ var srcA = GetSrcReg(context, op.SrcA);
+ var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+
+ EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo);
+ }
+
+ public static void ImulC(EmitterContext context)
+ {
+ InstImulC op = context.GetOp<InstImulC>();
+
+ var srcA = GetSrcReg(context, op.SrcA);
+ var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+ EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo);
+ }
+
+ public static void Imul32i(EmitterContext context)
+ {
+ InstImul32i op = context.GetOp<InstImul32i>();
+
+ var srcA = GetSrcReg(context, op.SrcA);
+ var srcB = GetSrcImm(context, op.Imm32);
+
+ EmitImad(context, srcA, srcB, Const(0), op.Dest, AvgMode.NoNeg, op.ASigned, op.BSigned, op.Hilo);
+ }
+
public static void IscaddR(EmitterContext context)
{
InstIscaddR op = context.GetOp<InstIscaddR>();
@@ -366,7 +406,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
// TODO: CC, X, corner cases.
}
- public static void EmitImad(
+ private static void EmitImad(
EmitterContext context,
Operand srcA,
Operand srcB,
@@ -407,7 +447,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
res = context.IMultiply(srcA, srcB);
}
- res = context.IAdd(res, srcC);
+ if (srcC.Type != OperandType.Constant || srcC.Value != 0)
+ {
+ res = context.IAdd(res, srcC);
+ }
// TODO: CC, X, SAT, and more?