diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2021-10-18 20:24:15 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-18 20:24:15 -0300 |
| commit | 63f1663fa959d8809d1762d99e9364565ba9b3d8 (patch) | |
| tree | 4317d6067048cbd912eed16b563b76d6b9ab6cfe /Ryujinx.Graphics.Shader/Translation | |
| parent | 052deebf26beb5e62e677e8d31c2eb024beaa82f (diff) | |
Fix shader 8-bit and 16-bit STS/STG (#2741)
* Fix 8 and 16-bit STG
* Fix 8 and 16-bit STS
* Shader cache version bump
Diffstat (limited to 'Ryujinx.Graphics.Shader/Translation')
4 files changed, 63 insertions, 12 deletions
diff --git a/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs b/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs index 113ece99..a8fef95b 100644 --- a/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs +++ b/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs @@ -627,6 +627,16 @@ namespace Ryujinx.Graphics.Shader.Translation 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); @@ -637,6 +647,16 @@ namespace Ryujinx.Graphics.Shader.Translation return context.Add(Instruction.StoreShared, null, a, b); } + public static Operand StoreShared16(this EmitterContext context, Operand a, Operand b) + { + return context.Add(Instruction.StoreShared16, null, a, b); + } + + public static Operand StoreShared8(this EmitterContext context, Operand a, Operand b) + { + return context.Add(Instruction.StoreShared8, null, a, b); + } + public static Operand UnpackDouble2x32High(this EmitterContext context, Operand a) { return UnpackDouble2x32(context, a, 1); diff --git a/Ryujinx.Graphics.Shader/Translation/GlobalMemory.cs b/Ryujinx.Graphics.Shader/Translation/GlobalMemory.cs index 75bd9ddf..1be63868 100644 --- a/Ryujinx.Graphics.Shader/Translation/GlobalMemory.cs +++ b/Ryujinx.Graphics.Shader/Translation/GlobalMemory.cs @@ -20,7 +20,9 @@ namespace Ryujinx.Graphics.Shader.Translation { return (inst.IsAtomic() && IsGlobalMr(inst)) || inst == Instruction.LoadGlobal || - inst == Instruction.StoreGlobal; + inst == Instruction.StoreGlobal || + inst == Instruction.StoreGlobal16 || + inst == Instruction.StoreGlobal8; } private static bool IsGlobalMr(Instruction inst) diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/GlobalToStorage.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/GlobalToStorage.cs index cc57102c..1cf43e5d 100644 --- a/Ryujinx.Graphics.Shader/Translation/Optimizations/GlobalToStorage.cs +++ b/Ryujinx.Graphics.Shader/Translation/Optimizations/GlobalToStorage.cs @@ -59,7 +59,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations Operation operation = (Operation)node.Value; bool isAtomic = operation.Inst.IsAtomic(); - bool isWrite = isAtomic || operation.Inst == Instruction.StoreGlobal; + bool isStg16Or8 = operation.Inst == Instruction.StoreGlobal16 || operation.Inst == Instruction.StoreGlobal8; + bool isWrite = isAtomic || operation.Inst == Instruction.StoreGlobal || isStg16Or8; config.SetUsedStorageBuffer(storageIndex, isWrite); @@ -78,12 +79,18 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations node.List.AddBefore(node, andOp); Operand byteOffset = Local(); - Operand wordOffset = Local(); + Operation subOp = new Operation(Instruction.Subtract, byteOffset, addrLow, baseAddrTrunc); - Operation subOp = new Operation(Instruction.Subtract, byteOffset, addrLow, baseAddrTrunc); + node.List.AddBefore(node, subOp); + + if (isStg16Or8) + { + return byteOffset; + } + + Operand wordOffset = Local(); Operation shrOp = new Operation(Instruction.ShiftRightU32, wordOffset, byteOffset, Const(2)); - node.List.AddBefore(node, subOp); node.List.AddBefore(node, shrOp); return wordOffset; @@ -113,7 +120,14 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations } else { - storageOp = new Operation(Instruction.StoreStorage, null, sources); + Instruction storeInst = operation.Inst switch + { + Instruction.StoreGlobal16 => Instruction.StoreStorage16, + Instruction.StoreGlobal8 => Instruction.StoreStorage8, + _ => Instruction.StoreStorage + }; + + storageOp = new Operation(storeInst, null, sources); } for (int index = 0; index < operation.SourcesCount; index++) diff --git a/Ryujinx.Graphics.Shader/Translation/Rewriter.cs b/Ryujinx.Graphics.Shader/Translation/Rewriter.cs index 47428520..02a0feda 100644 --- a/Ryujinx.Graphics.Shader/Translation/Rewriter.cs +++ b/Ryujinx.Graphics.Shader/Translation/Rewriter.cs @@ -49,7 +49,8 @@ namespace Ryujinx.Graphics.Shader.Translation Operation operation = (Operation)node.Value; bool isAtomic = operation.Inst.IsAtomic(); - bool isWrite = isAtomic || operation.Inst == Instruction.StoreGlobal; + bool isStg16Or8 = operation.Inst == Instruction.StoreGlobal16 || operation.Inst == Instruction.StoreGlobal8; + bool isWrite = isAtomic || operation.Inst == Instruction.StoreGlobal || isStg16Or8; Operation storageOp; @@ -95,14 +96,21 @@ namespace Ryujinx.Graphics.Shader.Translation Operand alignMask = Const(-config.GpuAccessor.QueryHostStorageBufferOffsetAlignment()); - Operand baseAddrTrunc = PrependOperation(Instruction.BitwiseAnd, sbBaseAddrLow, alignMask); - Operand byteOffset = PrependOperation(Instruction.Subtract, addrLow, baseAddrTrunc); - Operand wordOffset = PrependOperation(Instruction.ShiftRightU32, byteOffset, Const(2)); + Operand baseAddrTrunc = PrependOperation(Instruction.BitwiseAnd, sbBaseAddrLow, alignMask); + Operand byteOffset = PrependOperation(Instruction.Subtract, addrLow, baseAddrTrunc); Operand[] sources = new Operand[operation.SourcesCount]; sources[0] = sbSlot; - sources[1] = wordOffset; + + if (isStg16Or8) + { + sources[1] = byteOffset; + } + else + { + sources[1] = PrependOperation(Instruction.ShiftRightU32, byteOffset, Const(2)); + } for (int index = 2; index < operation.SourcesCount; index++) { @@ -121,7 +129,14 @@ namespace Ryujinx.Graphics.Shader.Translation } else { - storageOp = new Operation(Instruction.StoreStorage, null, sources); + Instruction storeInst = operation.Inst switch + { + Instruction.StoreGlobal16 => Instruction.StoreStorage16, + Instruction.StoreGlobal8 => Instruction.StoreStorage8, + _ => Instruction.StoreStorage + }; + + storageOp = new Operation(storeInst, null, sources); } for (int index = 0; index < operation.SourcesCount; index++) |
