mirror of
https://git.ryujinx.app/projects/Kenji-NX.git
synced 2026-10-06 11:18:54 +02:00
Implement PRMT shader instruction
This commit is contained in:
@@ -522,6 +522,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
|||||||
|
|
||||||
enum PMode
|
enum PMode
|
||||||
{
|
{
|
||||||
|
Idx = 0,
|
||||||
F4e = 1,
|
F4e = 1,
|
||||||
B4e = 2,
|
B4e = 2,
|
||||||
Rc8 = 3,
|
Rc8 = 3,
|
||||||
|
|||||||
@@ -215,34 +215,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction Pret is not implemented.");
|
context.TranslatorContext.GpuAccessor.Log("Shader instruction Pret is not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PrmtR(EmitterContext context)
|
|
||||||
{
|
|
||||||
context.GetOp<InstPrmtR>();
|
|
||||||
|
|
||||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtR is not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void PrmtI(EmitterContext context)
|
|
||||||
{
|
|
||||||
context.GetOp<InstPrmtI>();
|
|
||||||
|
|
||||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtI is not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void PrmtC(EmitterContext context)
|
|
||||||
{
|
|
||||||
context.GetOp<InstPrmtC>();
|
|
||||||
|
|
||||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtC is not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void PrmtRc(EmitterContext context)
|
|
||||||
{
|
|
||||||
context.GetOp<InstPrmtRc>();
|
|
||||||
|
|
||||||
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtRc is not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void R2b(EmitterContext context)
|
public static void R2b(EmitterContext context)
|
||||||
{
|
{
|
||||||
context.GetOp<InstR2b>();
|
context.GetOp<InstR2b>();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using Ryujinx.Graphics.Shader.Decoders;
|
using Ryujinx.Graphics.Shader.Decoders;
|
||||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
|
using System;
|
||||||
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
|
||||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
@@ -37,6 +37,38 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
context.Copy(GetDest(op.Dest), GetSrcImm(context, op.Imm32));
|
context.Copy(GetDest(op.Dest), GetSrcImm(context, op.Imm32));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void PrmtR(EmitterContext context)
|
||||||
|
{
|
||||||
|
context.GetOp<InstPrmtR>();
|
||||||
|
|
||||||
|
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtR is not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PrmtI(EmitterContext context)
|
||||||
|
{
|
||||||
|
InstPrmtI op = context.GetOp<InstPrmtI>();
|
||||||
|
|
||||||
|
Operand op1 = GetSrcReg(context, op.SrcA);
|
||||||
|
Operand control = GetSrcImm(context, op.Imm20);
|
||||||
|
Operand op2 = GetSrcReg(context, op.SrcC);
|
||||||
|
|
||||||
|
EmitPrmt(context, op1, control, op2, op.PMode, op.Dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PrmtC(EmitterContext context)
|
||||||
|
{
|
||||||
|
context.GetOp<InstPrmtC>();
|
||||||
|
|
||||||
|
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtC is not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PrmtRc(EmitterContext context)
|
||||||
|
{
|
||||||
|
context.GetOp<InstPrmtRc>();
|
||||||
|
|
||||||
|
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtRc is not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
public static void R2pR(EmitterContext context)
|
public static void R2pR(EmitterContext context)
|
||||||
{
|
{
|
||||||
InstR2pR op = context.GetOp<InstR2pR>();
|
InstR2pR op = context.GetOp<InstR2pR>();
|
||||||
@@ -169,6 +201,39 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
context.Copy(GetDest(op.Dest), src);
|
context.Copy(GetDest(op.Dest), src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SelR(EmitterContext context)
|
||||||
|
{
|
||||||
|
InstSelR op = context.GetOp<InstSelR>();
|
||||||
|
|
||||||
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
|
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||||
|
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
||||||
|
|
||||||
|
EmitSel(context, srcA, srcB, srcPred, op.Dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SelI(EmitterContext context)
|
||||||
|
{
|
||||||
|
InstSelI op = context.GetOp<InstSelI>();
|
||||||
|
|
||||||
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
|
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
||||||
|
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
||||||
|
|
||||||
|
EmitSel(context, srcA, srcB, srcPred, op.Dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SelC(EmitterContext context)
|
||||||
|
{
|
||||||
|
InstSelC op = context.GetOp<InstSelC>();
|
||||||
|
|
||||||
|
Operand srcA = GetSrcReg(context, op.SrcA);
|
||||||
|
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
||||||
|
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
||||||
|
|
||||||
|
EmitSel(context, srcA, srcB, srcPred, op.Dest);
|
||||||
|
}
|
||||||
|
|
||||||
private static Operand EmitLoadSubgroupLaneId(EmitterContext context)
|
private static Operand EmitLoadSubgroupLaneId(EmitterContext context)
|
||||||
{
|
{
|
||||||
if (context.TranslatorContext.GpuAccessor.QueryHostSubgroupSize() <= 32)
|
if (context.TranslatorContext.GpuAccessor.QueryHostSubgroupSize() <= 32)
|
||||||
@@ -215,37 +280,34 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SelR(EmitterContext context)
|
private static void EmitPrmt(EmitterContext context, Operand op1, Operand control, Operand op2, PMode pMode, int rd)
|
||||||
{
|
{
|
||||||
InstSelR op = context.GetOp<InstSelR>();
|
if (pMode == PMode.Idx)
|
||||||
|
{
|
||||||
|
Operand res = Const(0);
|
||||||
|
|
||||||
Operand srcA = GetSrcReg(context, op.SrcA);
|
for (int b = 0; b < 4; b++)
|
||||||
Operand srcB = GetSrcReg(context, op.SrcB);
|
{
|
||||||
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
Operand sel = context.ShiftRightU32(control, Const(b * 4));
|
||||||
|
Operand byteSel = context.BitwiseAnd(sel, Const(7));
|
||||||
|
Operand copySign = context.BitwiseAnd(sel, Const(8));
|
||||||
|
|
||||||
EmitSel(context, srcA, srcB, srcPred, op.Dest);
|
Operand srcOp = context.ConditionalSelect(context.BitwiseAnd(byteSel, Const(4)), op2, op1);
|
||||||
}
|
Operand srcValue = context.ShiftRightU32(srcOp, context.ShiftLeft(context.BitwiseAnd(byteSel, Const(3)), Const(3)));
|
||||||
|
Operand srcSign = context.ShiftRightS32(context.ShiftLeft(srcValue, Const(24)), Const(31));
|
||||||
|
|
||||||
public static void SelI(EmitterContext context)
|
srcValue = context.ConditionalSelect(copySign, srcSign, srcValue);
|
||||||
{
|
srcValue = context.BitwiseAnd(srcValue, Const(0xff));
|
||||||
InstSelI op = context.GetOp<InstSelI>();
|
|
||||||
|
|
||||||
Operand srcA = GetSrcReg(context, op.SrcA);
|
res = context.BitfieldInsert(res, srcValue, Const(b * 8), Const(8));
|
||||||
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
|
}
|
||||||
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
|
||||||
|
|
||||||
EmitSel(context, srcA, srcB, srcPred, op.Dest);
|
context.Copy(GetDest(rd), res);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
public static void SelC(EmitterContext context)
|
{
|
||||||
{
|
throw new NotImplementedException(pMode.ToString());
|
||||||
InstSelC op = context.GetOp<InstSelC>();
|
}
|
||||||
|
|
||||||
Operand srcA = GetSrcReg(context, op.SrcA);
|
|
||||||
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
|
|
||||||
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
|
|
||||||
|
|
||||||
EmitSel(context, srcA, srcB, srcPred, op.Dest);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EmitR2p(EmitterContext context, Operand value, Operand mask, ByteSel byteSel, bool ccpr)
|
private static void EmitR2p(EmitterContext context, Operand value, Operand mask, ByteSel byteSel, bool ccpr)
|
||||||
|
|||||||
Reference in New Issue
Block a user