diff options
author | gdkchan <gab.dark.100@gmail.com> | 2021-06-29 14:32:02 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-29 19:32:02 +0200 |
commit | fbb4019ed5c12c4a888c7b09db648ac595366896 (patch) | |
tree | a8be6bf5fc4f8b844683f1ef2ade588f3bb9bb0a /Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | |
parent | 8cc872fb60ec1b825655ba8dba06cc978fcd7e66 (diff) |
Initial support for separate GPU address spaces (#2394)
* Make GPU memory manager a member of GPU channel
* Move physical memory instance to the memory manager, and the caches to the physical memory
* PR feedback
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index 72ae0b10..efb0503c 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -1,6 +1,7 @@ using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Graphics.Gpu.Shader.Cache; using Ryujinx.Graphics.Gpu.Shader.Cache.Definition; using Ryujinx.Graphics.Gpu.State; @@ -492,7 +493,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { foreach (ShaderBundle cachedCpShader in list) { - if (IsShaderEqual(cachedCpShader, gpuVa)) + if (IsShaderEqual(state.Channel.MemoryManager, cachedCpShader, gpuVa)) { return cachedCpShader; } @@ -527,7 +528,7 @@ namespace Ryujinx.Graphics.Gpu.Shader isShaderCacheReadOnly = _cacheManager.IsReadOnly; // Compute hash and prepare data for shader disk cache comparison. - shaderCacheEntries = CacheHelper.CreateShaderCacheEntries(_context.MemoryManager, shaderContexts); + shaderCacheEntries = CacheHelper.CreateShaderCacheEntries(state.Channel.MemoryManager, shaderContexts); programCodeHash = CacheHelper.ComputeGuestHashFromCache(shaderCacheEntries); } @@ -542,7 +543,7 @@ namespace Ryujinx.Graphics.Gpu.Shader } // The shader isn't currently cached, translate it and compile it. - ShaderCodeHolder shader = TranslateShader(shaderContexts[0]); + ShaderCodeHolder shader = TranslateShader(state.Channel.MemoryManager, shaderContexts[0]); shader.HostShader = _context.Renderer.CompileShader(ShaderStage.Compute, shader.Program.Code); @@ -595,7 +596,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { foreach (ShaderBundle cachedGpShaders in list) { - if (IsShaderEqual(cachedGpShaders, addresses)) + if (IsShaderEqual(state.Channel.MemoryManager, cachedGpShaders, addresses)) { return cachedGpShaders; } @@ -647,7 +648,7 @@ namespace Ryujinx.Graphics.Gpu.Shader isShaderCacheReadOnly = _cacheManager.IsReadOnly; // Compute hash and prepare data for shader disk cache comparison. - shaderCacheEntries = CacheHelper.CreateShaderCacheEntries(_context.MemoryManager, shaderContexts); + shaderCacheEntries = CacheHelper.CreateShaderCacheEntries(state.Channel.MemoryManager, shaderContexts); programCodeHash = CacheHelper.ComputeGuestHashFromCache(shaderCacheEntries, tfd); } @@ -664,11 +665,11 @@ namespace Ryujinx.Graphics.Gpu.Shader // The shader isn't currently cached, translate it and compile it. ShaderCodeHolder[] shaders = new ShaderCodeHolder[Constants.ShaderStages]; - shaders[0] = TranslateShader(shaderContexts[1], shaderContexts[0]); - shaders[1] = TranslateShader(shaderContexts[2]); - shaders[2] = TranslateShader(shaderContexts[3]); - shaders[3] = TranslateShader(shaderContexts[4]); - shaders[4] = TranslateShader(shaderContexts[5]); + shaders[0] = TranslateShader(state.Channel.MemoryManager, shaderContexts[1], shaderContexts[0]); + shaders[1] = TranslateShader(state.Channel.MemoryManager, shaderContexts[2]); + shaders[2] = TranslateShader(state.Channel.MemoryManager, shaderContexts[3]); + shaders[3] = TranslateShader(state.Channel.MemoryManager, shaderContexts[4]); + shaders[4] = TranslateShader(state.Channel.MemoryManager, shaderContexts[5]); List<IShader> hostShaders = new List<IShader>(); @@ -724,7 +725,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// </summary> /// <param name="state">Current GPU state</param> /// <returns>Four transform feedback descriptors for the enabled TFBs, or null if TFB is disabled</returns> - private TransformFeedbackDescriptor[] GetTransformFeedbackDescriptors(GpuState state) + private static TransformFeedbackDescriptor[] GetTransformFeedbackDescriptors(GpuState state) { bool tfEnable = state.Get<Boolean32>(MethodOffset.TfEnable); @@ -752,21 +753,23 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <summary> /// Checks if compute shader code in memory is equal to the cached shader. /// </summary> + /// <param name="memoryManager">Memory manager used to access the GPU memory where the shader is located</param> /// <param name="cpShader">Cached compute shader</param> /// <param name="gpuVa">GPU virtual address of the shader code in memory</param> /// <returns>True if the code is different, false otherwise</returns> - private bool IsShaderEqual(ShaderBundle cpShader, ulong gpuVa) + private static bool IsShaderEqual(MemoryManager memoryManager, ShaderBundle cpShader, ulong gpuVa) { - return IsShaderEqual(cpShader.Shaders[0], gpuVa); + return IsShaderEqual(memoryManager, cpShader.Shaders[0], gpuVa); } /// <summary> /// Checks if graphics shader code from all stages in memory are equal to the cached shaders. /// </summary> + /// <param name="memoryManager">Memory manager used to access the GPU memory where the shader is located</param> /// <param name="gpShaders">Cached graphics shaders</param> /// <param name="addresses">GPU virtual addresses of all enabled shader stages</param> /// <returns>True if the code is different, false otherwise</returns> - private bool IsShaderEqual(ShaderBundle gpShaders, ShaderAddresses addresses) + private static bool IsShaderEqual(MemoryManager memoryManager, ShaderBundle gpShaders, ShaderAddresses addresses) { for (int stage = 0; stage < gpShaders.Shaders.Length; stage++) { @@ -783,7 +786,7 @@ namespace Ryujinx.Graphics.Gpu.Shader case 4: gpuVa = addresses.Fragment; break; } - if (!IsShaderEqual(shader, gpuVa, addresses.VertexA)) + if (!IsShaderEqual(memoryManager, shader, gpuVa, addresses.VertexA)) { return false; } @@ -795,24 +798,25 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <summary> /// Checks if the code of the specified cached shader is different from the code in memory. /// </summary> + /// <param name="memoryManager">Memory manager used to access the GPU memory where the shader is located</param> /// <param name="shader">Cached shader to compare with</param> /// <param name="gpuVa">GPU virtual address of the binary shader code</param> /// <param name="gpuVaA">Optional GPU virtual address of the "Vertex A" binary shader code</param> /// <returns>True if the code is different, false otherwise</returns> - private bool IsShaderEqual(ShaderCodeHolder shader, ulong gpuVa, ulong gpuVaA = 0) + private static bool IsShaderEqual(MemoryManager memoryManager, ShaderCodeHolder shader, ulong gpuVa, ulong gpuVaA = 0) { if (shader == null) { return true; } - ReadOnlySpan<byte> memoryCode = _context.MemoryManager.GetSpan(gpuVa, shader.Code.Length); + ReadOnlySpan<byte> memoryCode = memoryManager.GetSpan(gpuVa, shader.Code.Length); bool equals = memoryCode.SequenceEqual(shader.Code); if (equals && shader.Code2 != null) { - memoryCode = _context.MemoryManager.GetSpan(gpuVaA, shader.Code2.Length); + memoryCode = memoryManager.GetSpan(gpuVaA, shader.Code2.Length); equals = memoryCode.SequenceEqual(shader.Code2); } @@ -882,10 +886,14 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <summary> /// Translates a previously generated translator context to something that the host API accepts. /// </summary> + /// <param name="memoryManager">Memory manager used to access the GPU memory where the shader is located</param> /// <param name="translatorContext">Current translator context to translate</param> /// <param name="translatorContext2">Optional translator context of the shader that should be combined</param> /// <returns>Compiled graphics shader code</returns> - private ShaderCodeHolder TranslateShader(TranslatorContext translatorContext, TranslatorContext translatorContext2 = null) + private ShaderCodeHolder TranslateShader( + MemoryManager memoryManager, + TranslatorContext translatorContext, + TranslatorContext translatorContext2 = null) { if (translatorContext == null) { @@ -894,8 +902,8 @@ namespace Ryujinx.Graphics.Gpu.Shader if (translatorContext2 != null) { - byte[] codeA = _context.MemoryManager.GetSpan(translatorContext2.Address, translatorContext2.Size).ToArray(); - byte[] codeB = _context.MemoryManager.GetSpan(translatorContext.Address, translatorContext.Size).ToArray(); + byte[] codeA = memoryManager.GetSpan(translatorContext2.Address, translatorContext2.Size).ToArray(); + byte[] codeB = memoryManager.GetSpan(translatorContext.Address, translatorContext.Size).ToArray(); _dumper.Dump(codeA, compute: false, out string fullPathA, out string codePathA); _dumper.Dump(codeB, compute: false, out string fullPathB, out string codePathB); @@ -914,7 +922,7 @@ namespace Ryujinx.Graphics.Gpu.Shader } else { - byte[] code = _context.MemoryManager.GetSpan(translatorContext.Address, translatorContext.Size).ToArray(); + byte[] code = memoryManager.GetSpan(translatorContext.Address, translatorContext.Size).ToArray(); _dumper.Dump(code, translatorContext.Stage == ShaderStage.Compute, out string fullPath, out string codePath); |