aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2023-06-15 17:31:53 -0300
committerGitHub <noreply@github.com>2023-06-15 17:31:53 -0300
commitf92921a6d118aa9c6acdb3ecaa3cd61a19fe341e (patch)
tree6cba0d6ad1dc27df5750cf671cd75f709082203d /src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
parent32d21ddf17ff7d61d8185a79bec3f5d02706109b (diff)
Implement Load/Store Local/Shared and Atomic shared using new instructions (#5241)1.1.896
* Implement Load/Store Local/Shared and Atomic shared using new instructions * Remove now unused code * Fix base offset register overwrite * Fix missing storage buffer set index when generating GLSL for Vulkan * Shader cache version bump * Remove more unused code * Some PR feedback
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs')
-rw-r--r--src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs109
1 files changed, 51 insertions, 58 deletions
diff --git a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
index 9aa73820..99d7bec9 100644
--- a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
+++ b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
@@ -10,12 +10,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
static partial class InstEmit
{
- private enum MemoryRegion
- {
- Local,
- Shared
- }
-
public static void Atom(EmitterContext context)
{
InstAtom op = context.GetOp<InstAtom>();
@@ -51,7 +45,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
_ => AtomSize.U32
};
- Operand res = EmitAtomicOp(context, StorageKind.SharedMemory, op.AtomOp, size, offset, Const(0), value);
+ Operand id = Const(context.Config.ResourceManager.SharedMemoryId);
+ Operand res = EmitAtomicOp(context, StorageKind.SharedMemory, op.AtomOp, size, id, offset, value);
context.Copy(GetDest(op.Dest), res);
}
@@ -114,14 +109,14 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
InstLdl op = context.GetOp<InstLdl>();
- EmitLoad(context, MemoryRegion.Local, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
+ EmitLoad(context, StorageKind.LocalMemory, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
}
public static void Lds(EmitterContext context)
{
InstLds op = context.GetOp<InstLds>();
- EmitLoad(context, MemoryRegion.Shared, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
+ EmitLoad(context, StorageKind.SharedMemory, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
}
public static void Red(EmitterContext context)
@@ -144,14 +139,14 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
InstStl op = context.GetOp<InstStl>();
- EmitStore(context, MemoryRegion.Local, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
+ EmitStore(context, StorageKind.LocalMemory, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
}
public static void Sts(EmitterContext context)
{
InstSts op = context.GetOp<InstSts>();
- EmitStore(context, MemoryRegion.Shared, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
+ EmitStore(context, StorageKind.SharedMemory, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
}
private static Operand EmitLoadConstant(EmitterContext context, Operand slot, Operand offset)
@@ -192,8 +187,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
StorageKind storageKind,
AtomOp op,
AtomSize type,
- Operand addrLow,
- Operand addrHigh,
+ Operand e0,
+ Operand e1,
Operand value)
{
Operand res = Const(0);
@@ -203,7 +198,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
case AtomOp.Add:
if (type == AtomSize.S32 || type == AtomSize.U32)
{
- res = context.AtomicAdd(storageKind, addrLow, addrHigh, value);
+ res = context.AtomicAdd(storageKind, e0, e1, value);
}
else
{
@@ -213,7 +208,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
case AtomOp.And:
if (type == AtomSize.S32 || type == AtomSize.U32)
{
- res = context.AtomicAnd(storageKind, addrLow, addrHigh, value);
+ res = context.AtomicAnd(storageKind, e0, e1, value);
}
else
{
@@ -223,7 +218,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
case AtomOp.Xor:
if (type == AtomSize.S32 || type == AtomSize.U32)
{
- res = context.AtomicXor(storageKind, addrLow, addrHigh, value);
+ res = context.AtomicXor(storageKind, e0, e1, value);
}
else
{
@@ -233,7 +228,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
case AtomOp.Or:
if (type == AtomSize.S32 || type == AtomSize.U32)
{
- res = context.AtomicOr(storageKind, addrLow, addrHigh, value);
+ res = context.AtomicOr(storageKind, e0, e1, value);
}
else
{
@@ -243,11 +238,11 @@ namespace Ryujinx.Graphics.Shader.Instructions
case AtomOp.Max:
if (type == AtomSize.S32)
{
- res = context.AtomicMaxS32(storageKind, addrLow, addrHigh, value);
+ res = context.AtomicMaxS32(storageKind, e0, e1, value);
}
else if (type == AtomSize.U32)
{
- res = context.AtomicMaxU32(storageKind, addrLow, addrHigh, value);
+ res = context.AtomicMaxU32(storageKind, e0, e1, value);
}
else
{
@@ -257,11 +252,11 @@ namespace Ryujinx.Graphics.Shader.Instructions
case AtomOp.Min:
if (type == AtomSize.S32)
{
- res = context.AtomicMinS32(storageKind, addrLow, addrHigh, value);
+ res = context.AtomicMinS32(storageKind, e0, e1, value);
}
else if (type == AtomSize.U32)
{
- res = context.AtomicMinU32(storageKind, addrLow, addrHigh, value);
+ res = context.AtomicMinU32(storageKind, e0, e1, value);
}
else
{
@@ -275,7 +270,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
private static void EmitLoad(
EmitterContext context,
- MemoryRegion region,
+ StorageKind storageKind,
LsSize2 size,
Operand srcA,
int rd,
@@ -287,19 +282,19 @@ namespace Ryujinx.Graphics.Shader.Instructions
return;
}
+ int id = storageKind == StorageKind.LocalMemory
+ ? context.Config.ResourceManager.LocalMemoryId
+ : context.Config.ResourceManager.SharedMemoryId;
bool isSmallInt = size < LsSize2.B32;
- int count = 1;
-
- switch (size)
+ int count = size switch
{
- case LsSize2.B64: count = 2; break;
- case LsSize2.B128: count = 4; break;
- }
+ LsSize2.B64 => 2,
+ LsSize2.B128 => 4,
+ _ => 1
+ };
- Operand baseOffset = context.IAdd(srcA, Const(offset));
- Operand wordOffset = context.ShiftRightU32(baseOffset, Const(2)); // Word offset = byte offset / 4 (one word = 4 bytes).
- Operand bitOffset = GetBitOffset(context, baseOffset);
+ Operand baseOffset = context.Copy(srcA);
for (int index = 0; index < count; index++)
{
@@ -310,14 +305,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
break;
}
- Operand elemOffset = context.IAdd(wordOffset, Const(index));
- Operand value = null;
-
- switch (region)
- {
- case MemoryRegion.Local: value = context.LoadLocal(elemOffset); break;
- case MemoryRegion.Shared: value = context.LoadShared(elemOffset); break;
- }
+ Operand byteOffset = context.IAdd(baseOffset, Const(offset + index * 4));
+ Operand wordOffset = context.ShiftRightU32(byteOffset, Const(2)); // Word offset = byte offset / 4 (one word = 4 bytes).
+ Operand bitOffset = GetBitOffset(context, byteOffset);
+ Operand value = context.Load(storageKind, id, wordOffset);
if (isSmallInt)
{
@@ -360,7 +351,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
private static void EmitStore(
EmitterContext context,
- MemoryRegion region,
+ StorageKind storageKind,
LsSize2 size,
Operand srcA,
int rd,
@@ -372,52 +363,54 @@ namespace Ryujinx.Graphics.Shader.Instructions
return;
}
+ int id = storageKind == StorageKind.LocalMemory
+ ? context.Config.ResourceManager.LocalMemoryId
+ : context.Config.ResourceManager.SharedMemoryId;
bool isSmallInt = size < LsSize2.B32;
- int count = 1;
-
- switch (size)
+ int count = size switch
{
- case LsSize2.B64: count = 2; break;
- case LsSize2.B128: count = 4; break;
- }
+ LsSize2.B64 => 2,
+ LsSize2.B128 => 4,
+ _ => 1
+ };
- Operand baseOffset = context.IAdd(srcA, Const(offset));
- Operand wordOffset = context.ShiftRightU32(baseOffset, Const(2));
- Operand bitOffset = GetBitOffset(context, baseOffset);
+ Operand baseOffset = context.Copy(srcA);
for (int index = 0; index < count; index++)
{
bool isRz = rd + index >= RegisterConsts.RegisterZeroIndex;
Operand value = Register(isRz ? rd : rd + index, RegisterType.Gpr);
- Operand elemOffset = context.IAdd(wordOffset, Const(index));
+ Operand byteOffset = context.IAdd(baseOffset, Const(offset + index * 4));
+ Operand wordOffset = context.ShiftRightU32(byteOffset, Const(2));
+ Operand bitOffset = GetBitOffset(context, byteOffset);
- if (isSmallInt && region == MemoryRegion.Local)
+ if (isSmallInt && storageKind == StorageKind.LocalMemory)
{
- Operand word = context.LoadLocal(elemOffset);
+ Operand word = context.Load(storageKind, id, wordOffset);
value = InsertSmallInt(context, (LsSize)size, bitOffset, word, value);
}
- if (region == MemoryRegion.Local)
+ if (storageKind == StorageKind.LocalMemory)
{
- context.StoreLocal(elemOffset, value);
+ context.Store(storageKind, id, wordOffset, value);
}
- else if (region == MemoryRegion.Shared)
+ else if (storageKind == StorageKind.SharedMemory)
{
switch (size)
{
case LsSize2.U8:
case LsSize2.S8:
- context.StoreShared8(baseOffset, value);
+ context.Store(StorageKind.SharedMemory8, id, byteOffset, value);
break;
case LsSize2.U16:
case LsSize2.S16:
- context.StoreShared16(baseOffset, value);
+ context.Store(StorageKind.SharedMemory16, id, byteOffset, value);
break;
default:
- context.StoreShared(elemOffset, value);
+ context.Store(storageKind, id, wordOffset, value);
break;
}
}