diff options
author | gdkchan <gab.dark.100@gmail.com> | 2021-07-11 17:20:40 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-11 17:20:40 -0300 |
commit | 40b21cc3c4d2622bbd4f88d43073341854d9a671 (patch) | |
tree | 6e9dc6a42e7c0bae5b03db468481771d5a6937ef /Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | |
parent | b5190f16810eb77388c861d1d1773e19644808db (diff) |
Separate GPU engines (part 2/2) (#2440)
* 3D engine now uses DeviceState too, plus new state modification tracking
* Remove old methods code
* Remove GpuState and friends
* Optimize DeviceState, force inline some functions
* This change was not supposed to go in
* Proper channel initialization
* Optimize state read/write methods even more
* Fix debug build
* Do not dirty state if the write is redundant
* The YControl register should dirty either the viewport or front face state too, to update the host origin
* Avoid redundant vertex buffer updates
* Move state and get rid of the Ryujinx.Graphics.Gpu.State namespace
* Comments and nits
* Fix rebase
* PR feedback
* Move changed = false to improve codegen
* PR feedback
* Carry RyuJIT a bit more
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | 61 |
1 files changed, 30 insertions, 31 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index 031c95a9..e5c1fb83 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -1,15 +1,16 @@ using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.Gpu.Engine.Threed; using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Graphics.Gpu.Shader.Cache; using Ryujinx.Graphics.Gpu.Shader.Cache.Definition; -using Ryujinx.Graphics.Gpu.State; using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader.Translation; using System; using System.Collections.Generic; using System.Diagnostics; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -593,10 +594,12 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <remarks> /// This automatically translates, compiles and adds the code to the cache if not present. /// </remarks> - /// <param name="state">Current GPU state</param> + /// <param name="state">GPU state</param> + /// <param name="channel">GPU channel</param> + /// <param name="gas">GPU accessor state</param> /// <param name="addresses">Addresses of the shaders for each stage</param> /// <returns>Compiled graphics shader code</returns> - public ShaderBundle GetGraphicsShader(GpuState state, ShaderAddresses addresses) + public ShaderBundle GetGraphicsShader(ref ThreedClassState state, GpuChannel channel, GpuAccessorState gas, ShaderAddresses addresses) { bool isCached = _gpPrograms.TryGetValue(addresses, out List<ShaderBundle> list); @@ -604,7 +607,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { foreach (ShaderBundle cachedGpShaders in list) { - if (IsShaderEqual(state.Channel.MemoryManager, cachedGpShaders, addresses)) + if (IsShaderEqual(channel.MemoryManager, cachedGpShaders, addresses)) { return cachedGpShaders; } @@ -613,7 +616,7 @@ namespace Ryujinx.Graphics.Gpu.Shader TranslatorContext[] shaderContexts = new TranslatorContext[Constants.ShaderStages + 1]; - TransformFeedbackDescriptor[] tfd = GetTransformFeedbackDescriptors(state); + TransformFeedbackDescriptor[] tfd = GetTransformFeedbackDescriptors(ref state); TranslationFlags flags = DefaultFlags; @@ -626,14 +629,14 @@ namespace Ryujinx.Graphics.Gpu.Shader if (addresses.VertexA != 0) { - shaderContexts[0] = DecodeGraphicsShader(state, counts, flags | TranslationFlags.VertexA, ShaderStage.Vertex, addresses.VertexA); + shaderContexts[0] = DecodeGraphicsShader(channel, gas, counts, flags | TranslationFlags.VertexA, ShaderStage.Vertex, addresses.VertexA); } - shaderContexts[1] = DecodeGraphicsShader(state, counts, flags, ShaderStage.Vertex, addresses.Vertex); - shaderContexts[2] = DecodeGraphicsShader(state, counts, flags, ShaderStage.TessellationControl, addresses.TessControl); - shaderContexts[3] = DecodeGraphicsShader(state, counts, flags, ShaderStage.TessellationEvaluation, addresses.TessEvaluation); - shaderContexts[4] = DecodeGraphicsShader(state, counts, flags, ShaderStage.Geometry, addresses.Geometry); - shaderContexts[5] = DecodeGraphicsShader(state, counts, flags, ShaderStage.Fragment, addresses.Fragment); + shaderContexts[1] = DecodeGraphicsShader(channel, gas, counts, flags, ShaderStage.Vertex, addresses.Vertex); + shaderContexts[2] = DecodeGraphicsShader(channel, gas, counts, flags, ShaderStage.TessellationControl, addresses.TessControl); + shaderContexts[3] = DecodeGraphicsShader(channel, gas, counts, flags, ShaderStage.TessellationEvaluation, addresses.TessEvaluation); + shaderContexts[4] = DecodeGraphicsShader(channel, gas, counts, flags, ShaderStage.Geometry, addresses.Geometry); + shaderContexts[5] = DecodeGraphicsShader(channel, gas, counts, flags, ShaderStage.Fragment, addresses.Fragment); bool isShaderCacheEnabled = _cacheManager != null; bool isShaderCacheReadOnly = false; @@ -656,7 +659,7 @@ namespace Ryujinx.Graphics.Gpu.Shader isShaderCacheReadOnly = _cacheManager.IsReadOnly; // Compute hash and prepare data for shader disk cache comparison. - shaderCacheEntries = CacheHelper.CreateShaderCacheEntries(state.Channel.MemoryManager, shaderContexts); + shaderCacheEntries = CacheHelper.CreateShaderCacheEntries(channel.MemoryManager, shaderContexts); programCodeHash = CacheHelper.ComputeGuestHashFromCache(shaderCacheEntries, tfd); } @@ -673,11 +676,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(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]); + shaders[0] = TranslateShader(channel.MemoryManager, shaderContexts[1], shaderContexts[0]); + shaders[1] = TranslateShader(channel.MemoryManager, shaderContexts[2]); + shaders[2] = TranslateShader(channel.MemoryManager, shaderContexts[3]); + shaders[3] = TranslateShader(channel.MemoryManager, shaderContexts[4]); + shaders[4] = TranslateShader(channel.MemoryManager, shaderContexts[5]); List<IShader> hostShaders = new List<IShader>(); @@ -733,9 +736,9 @@ 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 static TransformFeedbackDescriptor[] GetTransformFeedbackDescriptors(GpuState state) + private static TransformFeedbackDescriptor[] GetTransformFeedbackDescriptors(ref ThreedClassState state) { - bool tfEnable = state.Get<Boolean32>(MethodOffset.TfEnable); + bool tfEnable = state.TfEnable; if (!tfEnable) { @@ -746,13 +749,13 @@ namespace Ryujinx.Graphics.Gpu.Shader for (int i = 0; i < Constants.TotalTransformFeedbackBuffers; i++) { - var tf = state.Get<TfState>(MethodOffset.TfState, i); + var tf = state.TfState[i]; int length = (int)Math.Min((uint)tf.VaryingsCount, 0x80); - var varyingLocations = state.GetSpan(MethodOffset.TfVaryingLocations + i * 0x80, length).ToArray(); + var varyingLocations = MemoryMarshal.Cast<uint, byte>(state.TfVaryingLocations[i].ToSpan()).Slice(0, length); - descs[i] = new TransformFeedbackDescriptor(tf.BufferIndex, tf.Stride, varyingLocations); + descs[i] = new TransformFeedbackDescriptor(tf.BufferIndex, tf.Stride, varyingLocations.ToArray()); } return descs; @@ -871,14 +874,16 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <remarks> /// This will combine the "Vertex A" and "Vertex B" shader stages, if specified, into one shader. /// </remarks> - /// <param name="state">Current GPU state</param> + /// <param name="channel">GPU channel</param> + /// <param name="gas">GPU accessor state</param> /// <param name="counts">Cumulative shader resource counts</param> /// <param name="flags">Flags that controls shader translation</param> /// <param name="stage">Shader stage</param> /// <param name="gpuVa">GPU virtual address of the shader code</param> /// <returns>The generated translator context</returns> private TranslatorContext DecodeGraphicsShader( - GpuState state, + GpuChannel channel, + GpuAccessorState gas, TranslationCounts counts, TranslationFlags flags, ShaderStage stage, @@ -889,13 +894,7 @@ namespace Ryujinx.Graphics.Gpu.Shader return null; } - GpuAccessorState gas = new GpuAccessorState( - state.Get<PoolState>(MethodOffset.TexturePoolState).Address.Pack(), - state.Get<PoolState>(MethodOffset.TexturePoolState).MaximumId, - state.Get<int>(MethodOffset.TextureBufferIndex), - state.Get<Boolean32>(MethodOffset.EarlyZForce)); - - GpuAccessor gpuAccessor = new GpuAccessor(_context, state.Channel, gas, (int)stage - 1); + GpuAccessor gpuAccessor = new GpuAccessor(_context, channel, gas, (int)stage - 1); var options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, flags); return Translator.CreateContext(gpuVa, gpuAccessor, options, counts); |