diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2022-01-10 12:08:00 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-10 12:08:00 -0300 |
| commit | 7f6b3d234a0dd82866e89930f05c520aca94946e (patch) | |
| tree | 49459142740eed719d431d9dc9ae37b0ff472ee8 /Ryujinx.Graphics.Shader/Instructions | |
| parent | 952c6e4d454082da900a447e6bd1deb272c150c2 (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')
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? |
