diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2021-10-28 19:53:12 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-28 19:53:12 -0300 |
| commit | 99445dd0a63f4a6fcb53e7818cda689d8299453b (patch) | |
| tree | 9d979f95e3e4cdf12999bc005655505953a60613 /Ryujinx.Graphics.Shader/Decoders/Decoder.cs | |
| parent | a7a40a77f2c07ea0ea9f6e7bfb57dbe9fce06db7 (diff) | |
Add support for fragment shader interlock (#2768)
* Support coherent images
* Add support for fragment shader interlock
* Change to tree based match approach
* Refactor + check for branch targets and external registers
* Make detection more robust
* Use Intel fragment shader ordering if interlock is not available, use nothing if both are not available
* Remove unused field
Diffstat (limited to 'Ryujinx.Graphics.Shader/Decoders/Decoder.cs')
| -rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/Decoder.cs | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs index b446e650..714aaad3 100644 --- a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs +++ b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs @@ -10,24 +10,25 @@ namespace Ryujinx.Graphics.Shader.Decoders { static class Decoder { - public static Block[][] Decode(ShaderConfig config, ulong startAddress) + public static DecodedProgram Decode(ShaderConfig config, ulong startAddress) { - List<Block[]> funcs = new List<Block[]>(); + Queue<DecodedFunction> functionsQueue = new Queue<DecodedFunction>(); + Dictionary<ulong, DecodedFunction> functionsVisited = new Dictionary<ulong, DecodedFunction>(); - Queue<ulong> funcQueue = new Queue<ulong>(); - HashSet<ulong> funcVisited = new HashSet<ulong>(); - - void EnqueueFunction(ulong funcAddress) + DecodedFunction EnqueueFunction(ulong address) { - if (funcVisited.Add(funcAddress)) + if (!functionsVisited.TryGetValue(address, out DecodedFunction function)) { - funcQueue.Enqueue(funcAddress); + functionsVisited.Add(address, function = new DecodedFunction(address)); + functionsQueue.Enqueue(function); } + + return function; } - funcQueue.Enqueue(0); + DecodedFunction mainFunction = EnqueueFunction(0); - while (funcQueue.TryDequeue(out ulong funcAddress)) + while (functionsQueue.TryDequeue(out DecodedFunction currentFunction)) { List<Block> blocks = new List<Block>(); Queue<Block> workQueue = new Queue<Block>(); @@ -46,7 +47,7 @@ namespace Ryujinx.Graphics.Shader.Decoders return block; } - GetBlock(funcAddress); + GetBlock(currentFunction.Address); bool hasNewTarget; @@ -108,7 +109,7 @@ namespace Ryujinx.Graphics.Shader.Decoders if (lastOp.Name == InstName.Cal) { - EnqueueFunction(lastOp.GetAbsoluteAddress()); + EnqueueFunction(lastOp.GetAbsoluteAddress()).AddCaller(currentFunction); } else if (lastOp.Name == InstName.Bra) { @@ -157,10 +158,10 @@ namespace Ryujinx.Graphics.Shader.Decoders } while (hasNewTarget); - funcs.Add(blocks.ToArray()); + currentFunction.SetBlocks(blocks.ToArray()); } - return funcs.ToArray(); + return new DecodedProgram(mainFunction, functionsVisited); } private static bool BinarySearch(List<Block> blocks, ulong address, out int index) |
