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
This commit is contained in:
parent
952c6e4d45
commit
7f6b3d234a
9 changed files with 108 additions and 68 deletions
|
@ -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>();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue