Add ATOMS, LDS, POPC, RED, STS and VOTE shader instructions, start changing the way how global memory is handled
This commit is contained in:
@ -256,7 +256,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||
{
|
||||
int value = operation.GetSource(0).Value;
|
||||
|
||||
value = (value >> operation.ComponentIndex * 16) & 0xffff;
|
||||
value = (value >> operation.Index * 16) & 0xffff;
|
||||
|
||||
operation.TurnIntoCopy(ConstF(HalfConversion.HalfToSingle(value)));
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||
{
|
||||
static class GlobalToStorage
|
||||
@ -27,7 +25,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||
continue;
|
||||
}
|
||||
|
||||
if (operation.Inst == Instruction.LoadGlobal ||
|
||||
if (operation.Inst.IsAtomic() ||
|
||||
operation.Inst == Instruction.LoadGlobal ||
|
||||
operation.Inst == Instruction.StoreGlobal)
|
||||
{
|
||||
Operand source = operation.GetSource(0);
|
||||
@ -51,18 +50,31 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||
|
||||
Operation storageOp;
|
||||
|
||||
if (operation.Inst == Instruction.LoadGlobal)
|
||||
if (operation.Inst.IsAtomic())
|
||||
{
|
||||
Operand[] sources = new Operand[operation.SourcesCount];
|
||||
|
||||
for (int index = 0; index < operation.SourcesCount; index++)
|
||||
{
|
||||
sources[index] = operation.GetSource(index);
|
||||
}
|
||||
|
||||
Instruction inst = (operation.Inst & ~Instruction.MrMask) | Instruction.MrStorage;
|
||||
|
||||
storageOp = new Operation(inst, storageIndex, operation.Dest, sources);
|
||||
}
|
||||
else if (operation.Inst == Instruction.LoadGlobal)
|
||||
{
|
||||
Operand source = operation.GetSource(0);
|
||||
|
||||
storageOp = new Operation(Instruction.LoadStorage, operation.Dest, Const(storageIndex), source);
|
||||
storageOp = new Operation(Instruction.LoadStorage, storageIndex, operation.Dest, source);
|
||||
}
|
||||
else
|
||||
{
|
||||
Operand src1 = operation.GetSource(0);
|
||||
Operand src2 = operation.GetSource(1);
|
||||
|
||||
storageOp = new Operation(Instruction.StoreStorage, null, Const(storageIndex), src1, src2);
|
||||
storageOp = new Operation(Instruction.StoreStorage, storageIndex, null, src1, src2);
|
||||
}
|
||||
|
||||
for (int index = 0; index < operation.SourcesCount; index++)
|
||||
@ -114,6 +126,11 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int GetStorageCbOffset(ShaderStage stage, int slot)
|
||||
{
|
||||
return GetStorageBaseCbOffset(stage) + slot * StorageDescSize;
|
||||
}
|
||||
|
||||
private static int GetStorageBaseCbOffset(ShaderStage stage)
|
||||
{
|
||||
switch (stage)
|
||||
|
@ -133,7 +133,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||
|
||||
if (operation.GetSource(0) == dest)
|
||||
{
|
||||
operation.TurnIntoCopy(operation.ComponentIndex == 1 ? src1 : src0);
|
||||
operation.TurnIntoCopy(operation.Index == 1 ? src1 : src0);
|
||||
|
||||
modified = true;
|
||||
}
|
||||
@ -251,7 +251,30 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||
|
||||
private static bool IsUnused(INode node)
|
||||
{
|
||||
return DestIsLocalVar(node) && node.Dest.UseOps.Count == 0;
|
||||
return !HasSideEffects(node) && DestIsLocalVar(node) && node.Dest.UseOps.Count == 0;
|
||||
}
|
||||
|
||||
private static bool HasSideEffects(INode node)
|
||||
{
|
||||
if (node is Operation operation)
|
||||
{
|
||||
switch (operation.Inst & Instruction.Mask)
|
||||
{
|
||||
case Instruction.AtomicAdd:
|
||||
case Instruction.AtomicAnd:
|
||||
case Instruction.AtomicCompareAndSwap:
|
||||
case Instruction.AtomicMaxS32:
|
||||
case Instruction.AtomicMaxU32:
|
||||
case Instruction.AtomicMinS32:
|
||||
case Instruction.AtomicMinU32:
|
||||
case Instruction.AtomicOr:
|
||||
case Instruction.AtomicSwap:
|
||||
case Instruction.AtomicXor:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool DestIsLocalVar(INode node)
|
||||
|
Reference in New Issue
Block a user