Implement shader storage buffer operations using new Load/Store instructions (#4993)

* Implement storage buffer operations using new Load/Store instruction

* Extend GenerateMultiTargetStorageOp to also match access with constant offset, and log and comments

* Remove now unused code

* Catch more complex cases of global memory usage

* Shader cache version bump

* Extend global access elimination to work with more shared memory cases

* Change alignment requirement from 16 bytes to 8 bytes, handle cases where we need more than 16 storage buffers

* Tweak preferencing to catch more cases

* Enable CB0 elimination even when host storage buffer alignment is > 16 (for Intel)

* Fix storage buffer bindings

* Simplify some code

* Shader cache version bump

* Fix typo

* Extend global memory elimination to handle shared memory with multiple possible offsets and local memory
This commit is contained in:
gdkchan 2023-06-03 20:12:18 -03:00 committed by GitHub
parent 81c9052847
commit 21c9ac6240
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 1468 additions and 1259 deletions

View file

@ -57,6 +57,56 @@ namespace Ryujinx.Graphics.Shader.Translation
return context.Add(Instruction.AtomicXor, storageKind, Local(), a, b, c);
}
public static Operand AtomicAdd(this EmitterContext context, StorageKind storageKind, int binding, Operand e0, Operand e1, Operand value)
{
return context.Add(Instruction.AtomicAdd, storageKind, Local(), Const(binding), e0, e1, value);
}
public static Operand AtomicAnd(this EmitterContext context, StorageKind storageKind, int binding, Operand e0, Operand e1, Operand value)
{
return context.Add(Instruction.AtomicAnd, storageKind, Local(), Const(binding), e0, e1, value);
}
public static Operand AtomicCompareAndSwap(this EmitterContext context, StorageKind storageKind, int binding, Operand e0, Operand e1, Operand compare, Operand value)
{
return context.Add(Instruction.AtomicCompareAndSwap, storageKind, Local(), Const(binding), e0, e1, compare, value);
}
public static Operand AtomicMaxS32(this EmitterContext context, StorageKind storageKind, int binding, Operand e0, Operand e1, Operand value)
{
return context.Add(Instruction.AtomicMaxS32, storageKind, Local(), Const(binding), e0, e1, value);
}
public static Operand AtomicMaxU32(this EmitterContext context, StorageKind storageKind, int binding, Operand e0, Operand e1, Operand value)
{
return context.Add(Instruction.AtomicMaxU32, storageKind, Local(), Const(binding), e0, e1, value);
}
public static Operand AtomicMinS32(this EmitterContext context, StorageKind storageKind, int binding, Operand e0, Operand e1, Operand value)
{
return context.Add(Instruction.AtomicMinS32, storageKind, Local(), Const(binding), e0, e1, value);
}
public static Operand AtomicMinU32(this EmitterContext context, StorageKind storageKind, int binding, Operand e0, Operand e1, Operand value)
{
return context.Add(Instruction.AtomicMinU32, storageKind, Local(), Const(binding), e0, e1, value);
}
public static Operand AtomicOr(this EmitterContext context, StorageKind storageKind, int binding, Operand e0, Operand e1, Operand value)
{
return context.Add(Instruction.AtomicOr, storageKind, Local(), Const(binding), e0, e1, value);
}
public static Operand AtomicSwap(this EmitterContext context, StorageKind storageKind, int binding, Operand e0, Operand e1, Operand value)
{
return context.Add(Instruction.AtomicSwap, storageKind, Local(), Const(binding), e0, e1, value);
}
public static Operand AtomicXor(this EmitterContext context, StorageKind storageKind, int binding, Operand e0, Operand e1, Operand value)
{
return context.Add(Instruction.AtomicXor, storageKind, Local(), Const(binding), e0, e1, value);
}
public static Operand Ballot(this EmitterContext context, Operand a)
{
return context.Add(Instruction.Ballot, Local(), a);
@ -554,6 +604,11 @@ namespace Ryujinx.Graphics.Shader.Translation
return context.Add(fpType | Instruction.IsNan, Local(), a);
}
public static Operand Load(this EmitterContext context, StorageKind storageKind, Operand e0, Operand e1)
{
return context.Add(Instruction.Load, storageKind, Local(), e0, e1);
}
public static Operand Load(this EmitterContext context, StorageKind storageKind, int binding)
{
return context.Add(Instruction.Load, storageKind, Local(), Const(binding));
@ -606,11 +661,6 @@ namespace Ryujinx.Graphics.Shader.Translation
: context.Load(storageKind, (int)ioVariable, arrayIndex, elemIndex);
}
public static Operand LoadGlobal(this EmitterContext context, Operand a, Operand b)
{
return context.Add(Instruction.LoadGlobal, Local(), a, b);
}
public static Operand LoadLocal(this EmitterContext context, Operand a)
{
return context.Add(Instruction.LoadLocal, Local(), a);
@ -655,7 +705,6 @@ namespace Ryujinx.Graphics.Shader.Translation
public static void Return(this EmitterContext context)
{
context.PrepareForReturn();
context.Add(Instruction.Return);
}
@ -699,6 +748,16 @@ namespace Ryujinx.Graphics.Shader.Translation
return context.Add(Instruction.ShuffleXor, (Local(), Local()), a, b, c);
}
public static Operand Store(this EmitterContext context, StorageKind storageKind, Operand e0, Operand e1, Operand value)
{
return context.Add(Instruction.Store, storageKind, null, e0, e1, value);
}
public static Operand Store(this EmitterContext context, StorageKind storageKind, int binding, Operand e0, Operand e1, Operand value)
{
return context.Add(Instruction.Store, storageKind, null, Const(binding), e0, e1, value);
}
public static Operand Store(
this EmitterContext context,
StorageKind storageKind,
@ -738,21 +797,6 @@ namespace Ryujinx.Graphics.Shader.Translation
: context.Add(Instruction.Store, storageKind, null, Const((int)ioVariable), arrayIndex, elemIndex, value);
}
public static Operand StoreGlobal(this EmitterContext context, Operand a, Operand b, Operand c)
{
return context.Add(Instruction.StoreGlobal, null, a, b, c);
}
public static Operand StoreGlobal16(this EmitterContext context, Operand a, Operand b, Operand c)
{
return context.Add(Instruction.StoreGlobal16, null, a, b, c);
}
public static Operand StoreGlobal8(this EmitterContext context, Operand a, Operand b, Operand c)
{
return context.Add(Instruction.StoreGlobal8, null, a, b, c);
}
public static Operand StoreLocal(this EmitterContext context, Operand a, Operand b)
{
return context.Add(Instruction.StoreLocal, null, a, b);