diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2020-10-03 02:43:33 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-03 15:43:33 +1000 |
| commit | 0954e76a261235107b2255c33de595d188570274 (patch) | |
| tree | 719e71e2938e808ca1164aa0da69f95d23248a88 | |
| parent | 86412ed30a5e28a7c11ba30c3987bdebeeb903c1 (diff) | |
Improve BRX target detection heuristics (#1591)
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs | 10 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs | 11 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/Decoder.cs | 15 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/IGpuAccessor.cs | 5 |
4 files changed, 39 insertions, 2 deletions
diff --git a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs index ace94442..59b6d1e5 100644 --- a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs +++ b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs @@ -311,6 +311,16 @@ namespace Ryujinx.Graphics.Gpu.Memory } /// <summary> + /// Checks if a given page is mapped. + /// </summary> + /// <param name="gpuVa">GPU virtual address of the page to check</param> + /// <returns>True if the page is mapped, false otherwise</returns> + public bool IsMapped(ulong gpuVa) + { + return Translate(gpuVa) != PteUnmapped; + } + + /// <summary> /// Translates a GPU virtual address to a CPU virtual address. /// </summary> /// <param name="gpuVa">GPU virtual address to be translated</param> diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs index d726bcb8..310eee38 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs @@ -3,7 +3,6 @@ using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Gpu.State; using Ryujinx.Graphics.Shader; -using System; namespace Ryujinx.Graphics.Gpu.Shader { @@ -85,6 +84,16 @@ namespace Ryujinx.Graphics.Gpu.Shader } /// <summary> + /// Checks if a given memory address is mapped. + /// </summary> + /// <param name="address">GPU virtual address to be checked</param> + /// <returns>True if the address is mapped, false otherwise</returns> + public bool MemoryMapped(ulong address) + { + return _context.MemoryManager.IsMapped(address); + } + + /// <summary> /// Queries Local Size X for compute shaders. /// </summary> /// <returns>Local Size X</returns> diff --git a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs index e2c9212b..a15d7f9e 100644 --- a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs +++ b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs @@ -128,7 +128,7 @@ namespace Ryujinx.Graphics.Shader.Decoders } // Do we have a block after the current one? - if (!IsExit(currBlock.GetLastOp()) && currBlock.BrIndir != null) + if (currBlock.BrIndir != null && HasBlockAfter(gpuAccessor, currBlock, startAddress)) { bool targetVisited = visited.ContainsKey(currBlock.EndAddress); @@ -154,6 +154,19 @@ namespace Ryujinx.Graphics.Shader.Decoders return blocks.ToArray(); } + private static bool HasBlockAfter(IGpuAccessor gpuAccessor, Block currBlock, ulong startAdddress) + { + if (!gpuAccessor.MemoryMapped(startAdddress + currBlock.EndAddress) || + !gpuAccessor.MemoryMapped(startAdddress + currBlock.EndAddress + 7)) + { + return false; + } + + ulong inst = gpuAccessor.MemoryRead<ulong>(startAdddress + currBlock.EndAddress); + + return inst != 0UL; + } + private static bool BinarySearch(List<Block> blocks, ulong address, out int index) { index = 0; diff --git a/Ryujinx.Graphics.Shader/IGpuAccessor.cs b/Ryujinx.Graphics.Shader/IGpuAccessor.cs index e10d869b..59069302 100644 --- a/Ryujinx.Graphics.Shader/IGpuAccessor.cs +++ b/Ryujinx.Graphics.Shader/IGpuAccessor.cs @@ -9,6 +9,11 @@ T MemoryRead<T>(ulong address) where T : unmanaged; + public bool MemoryMapped(ulong address) + { + return true; + } + public int QueryComputeLocalSizeX() { return 1; |
