diff options
| author | EmulationFanatic <62343878+EmulationFanatic@users.noreply.github.com> | 2021-05-19 11:39:19 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-05-19 11:39:19 -0700 |
| commit | b5c72b44dee2fd977d7cca5aa3c29ef1e2286aa7 (patch) | |
| tree | ae064aca256cb6193f6908cc9698660043754008 /Ryujinx.Graphics.OpenGL | |
| parent | 0129250c2e169c7386f7e2868cc055f8ec55c005 (diff) | |
| parent | 778011c12ae7905173e02665f397a96686863b89 (diff) | |
Merge pull request #2177 from riperiperi/feature/parallel-shader-cache
Allow parallel shader compilation when loading a shader cache
Diffstat (limited to 'Ryujinx.Graphics.OpenGL')
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/HwCapabilities.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Program.cs | 80 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Renderer.cs | 16 |
3 files changed, 64 insertions, 34 deletions
diff --git a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs index 7c2acacd..c994113d 100644 --- a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs +++ b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs @@ -10,6 +10,7 @@ namespace Ryujinx.Graphics.OpenGL private static readonly Lazy<bool> _supportsPolygonOffsetClamp = new Lazy<bool>(() => HasExtension("GL_EXT_polygon_offset_clamp")); private static readonly Lazy<bool> _supportsViewportSwizzle = new Lazy<bool>(() => HasExtension("GL_NV_viewport_swizzle")); private static readonly Lazy<bool> _supportsSeamlessCubemapPerTexture = new Lazy<bool>(() => HasExtension("GL_ARB_seamless_cubemap_per_texture")); + private static readonly Lazy<bool> _supportsParallelShaderCompile = new Lazy<bool>(() => HasExtension("GL_ARB_parallel_shader_compile")); private static readonly Lazy<int> _maximumComputeSharedMemorySize = new Lazy<int>(() => GetLimit(All.MaxComputeSharedMemorySize)); private static readonly Lazy<int> _storageBufferOffsetAlignment = new Lazy<int>(() => GetLimit(All.ShaderStorageBufferOffsetAlignment)); @@ -34,6 +35,7 @@ namespace Ryujinx.Graphics.OpenGL public static bool SupportsPolygonOffsetClamp => _supportsPolygonOffsetClamp.Value; public static bool SupportsViewportSwizzle => _supportsViewportSwizzle.Value; public static bool SupportsSeamlessCubemapPerTexture => _supportsSeamlessCubemapPerTexture.Value; + public static bool SupportsParallelShaderCompile => _supportsParallelShaderCompile.Value; public static bool SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia; public static bool RequiresSyncFlush => _gpuVendor.Value == GpuVendor.Amd || _gpuVendor.Value == GpuVendor.IntelWindows || _gpuVendor.Value == GpuVendor.IntelUnix; public static bool SupportsMismatchingViewFormat => _gpuVendor.Value != GpuVendor.Amd && _gpuVendor.Value != GpuVendor.IntelWindows; diff --git a/Ryujinx.Graphics.OpenGL/Program.cs b/Ryujinx.Graphics.OpenGL/Program.cs index d39e181d..decc75b1 100644 --- a/Ryujinx.Graphics.OpenGL/Program.cs +++ b/Ryujinx.Graphics.OpenGL/Program.cs @@ -13,11 +13,26 @@ namespace Ryujinx.Graphics.OpenGL { public int Handle { get; private set; } - public int FragmentIsBgraUniform { get; } - public int FragmentRenderScaleUniform { get; } - public int ComputeRenderScaleUniform { get; } + public int FragmentIsBgraUniform { get; private set; } + public int FragmentRenderScaleUniform { get; private set; } + public int ComputeRenderScaleUniform { get; private set; } - public bool IsLinked { get; private set; } + public bool IsLinked + { + get + { + if (_status == ProgramLinkStatus.Incomplete) + { + CheckProgramLink(true); + } + + return _status == ProgramLinkStatus.Success; + } + } + + private bool _initialized; + private ProgramLinkStatus _status = ProgramLinkStatus.Incomplete; + private IShader[] _shaders; public Program(IShader[] shaders, TransformFeedbackDescriptor[] transformFeedbackDescriptors) { @@ -82,18 +97,7 @@ namespace Ryujinx.Graphics.OpenGL GL.LinkProgram(Handle); - for (int index = 0; index < shaders.Length; index++) - { - int shaderHandle = ((Shader)shaders[index]).Handle; - - GL.DetachShader(Handle, shaderHandle); - } - - CheckProgramLink(); - - FragmentIsBgraUniform = GL.GetUniformLocation(Handle, "is_bgra"); - FragmentRenderScaleUniform = GL.GetUniformLocation(Handle, "fp_renderScale"); - ComputeRenderScaleUniform = GL.GetUniformLocation(Handle, "cp_renderScale"); + _shaders = shaders; } public Program(ReadOnlySpan<byte> code) @@ -109,32 +113,60 @@ namespace Ryujinx.Graphics.OpenGL GL.ProgramBinary(Handle, binaryFormat, (IntPtr)ptr, code.Length - 4); } } - - CheckProgramLink(); - - FragmentIsBgraUniform = GL.GetUniformLocation(Handle, "is_bgra"); - FragmentRenderScaleUniform = GL.GetUniformLocation(Handle, "fp_renderScale"); - ComputeRenderScaleUniform = GL.GetUniformLocation(Handle, "cp_renderScale"); } public void Bind() { + if (!_initialized) + { + FragmentIsBgraUniform = GL.GetUniformLocation(Handle, "is_bgra"); + FragmentRenderScaleUniform = GL.GetUniformLocation(Handle, "fp_renderScale"); + ComputeRenderScaleUniform = GL.GetUniformLocation(Handle, "cp_renderScale"); + + _initialized = true; + } + GL.UseProgram(Handle); } - private void CheckProgramLink() + public ProgramLinkStatus CheckProgramLink(bool blocking) { + if (!blocking && HwCapabilities.SupportsParallelShaderCompile) + { + GL.GetProgram(Handle, (GetProgramParameterName)ArbParallelShaderCompile.CompletionStatusArb, out int completed); + + if (completed == 0) + { + return ProgramLinkStatus.Incomplete; + } + } + GL.GetProgram(Handle, GetProgramParameterName.LinkStatus, out int status); + if (_shaders != null) + { + for (int index = 0; index < _shaders.Length; index++) + { + int shaderHandle = ((Shader)_shaders[index]).Handle; + + GL.DetachShader(Handle, shaderHandle); + } + + _shaders = null; + } + if (status == 0) { // Use GL.GetProgramInfoLog(Handle), it may be too long to print on the log. + _status = ProgramLinkStatus.Failure; Logger.Debug?.Print(LogClass.Gpu, "Shader linking failed."); } else { - IsLinked = true; + _status = ProgramLinkStatus.Success; } + + return _status; } public byte[] GetBinary() diff --git a/Ryujinx.Graphics.OpenGL/Renderer.cs b/Ryujinx.Graphics.OpenGL/Renderer.cs index b909f792..7416cdd7 100644 --- a/Ryujinx.Graphics.OpenGL/Renderer.cs +++ b/Ryujinx.Graphics.OpenGL/Renderer.cs @@ -131,6 +131,11 @@ namespace Ryujinx.Graphics.OpenGL PrintGpuInformation(); + if (HwCapabilities.SupportsParallelShaderCompile) + { + GL.Arb.MaxShaderCompilerThreads(Math.Min(Environment.ProcessorCount, 8)); + } + _counters.Initialize(); } @@ -178,16 +183,7 @@ namespace Ryujinx.Graphics.OpenGL public IProgram LoadProgramBinary(byte[] programBinary) { - Program program = new Program(programBinary); - - if (program.IsLinked) - { - return program; - } - - program.Dispose(); - - return null; + return new Program(programBinary); } public void CreateSync(ulong id) |
