aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL/Program.cs
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2021-03-29 21:52:25 +0100
committerriperiperi <rhy3756547@hotmail.com>2021-04-18 17:33:58 +0100
commitddf4b92a9cfbe98f798dd86a7c123b065a832d51 (patch)
treeaead39221f1975579d00446f181750a299960bca /Ryujinx.Graphics.OpenGL/Program.cs
parentbb43219f1dfc2fc35e21bcccab4d96fba5e01f34 (diff)
Implement parallel host shader cache compilation.
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Program.cs')
-rw-r--r--Ryujinx.Graphics.OpenGL/Program.cs80
1 files changed, 56 insertions, 24 deletions
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()