aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2023-05-20 16:19:26 -0300
committerGitHub <noreply@github.com>2023-05-20 16:19:26 -0300
commit402f05b8ef013807997589ecc0a8ff50267dcd23 (patch)
tree8e3b06c2ce3e3ccd4b443a4c68365251acc668fa /src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
parentfb27042e01b0fa110184673d436ec96ec8cf20c7 (diff)
Replace constant buffer access on shader with new Load instruction (#4646)1.1.811
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs')
-rw-r--r--src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs39
1 files changed, 36 insertions, 3 deletions
diff --git a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
index c73c6b2a..6f5913eb 100644
--- a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
+++ b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
@@ -1,6 +1,7 @@
using Ryujinx.Graphics.Shader.Decoders;
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using Ryujinx.Graphics.Shader.Translation;
+using System.Numerics;
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
@@ -80,7 +81,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
Operand addr = context.IAdd(srcA, Const(Imm16ToSInt(op.CbufOffset)));
Operand wordOffset = context.ShiftRightU32(addr, Const(2));
- Operand bitOffset = GetBitOffset(context, addr);
for (int index = 0; index < count; index++)
{
@@ -92,11 +92,11 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
Operand offset = context.IAdd(wordOffset, Const(index));
- Operand value = context.LoadConstant(slot, offset);
+ Operand value = EmitLoadConstant(context, slot, offset);
if (isSmallInt)
{
- value = ExtractSmallInt(context, (LsSize)op.LsSize, bitOffset, value);
+ value = ExtractSmallInt(context, (LsSize)op.LsSize, GetBitOffset(context, addr), value);
}
context.Copy(Register(dest), value);
@@ -154,6 +154,39 @@ namespace Ryujinx.Graphics.Shader.Instructions
EmitStore(context, MemoryRegion.Shared, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
}
+ private static Operand EmitLoadConstant(EmitterContext context, Operand slot, Operand offset)
+ {
+ Operand vecIndex = context.ShiftRightU32(offset, Const(2));
+ Operand elemIndex = context.BitwiseAnd(offset, Const(3));
+
+ if (slot.Type == OperandType.Constant)
+ {
+ int binding = context.Config.ResourceManager.GetConstantBufferBinding(slot.Value);
+ return context.Load(StorageKind.ConstantBuffer, binding, Const(0), vecIndex, elemIndex);
+ }
+ else
+ {
+ Operand value = Const(0);
+
+ uint cbUseMask = context.Config.GpuAccessor.QueryConstantBufferUse();
+
+ while (cbUseMask != 0)
+ {
+ int cbIndex = BitOperations.TrailingZeroCount(cbUseMask);
+ int binding = context.Config.ResourceManager.GetConstantBufferBinding(cbIndex);
+
+ Operand isCurrent = context.ICompareEqual(slot, Const(cbIndex));
+ Operand currentValue = context.Load(StorageKind.ConstantBuffer, binding, Const(0), vecIndex, elemIndex);
+
+ value = context.ConditionalSelect(isCurrent, currentValue, value);
+
+ cbUseMask &= ~(1u << cbIndex);
+ }
+
+ return value;
+ }
+ }
+
private static Operand EmitAtomicOp(
EmitterContext context,
StorageKind storageKind,