From 33294f9c810c8c91761443e02cc37ea8c7d2a8fe Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 3 Feb 2014 07:43:47 +0000 Subject: [PATCH] dont malfunction when compiling filter shaders on low-spec systems; just make the filters unavailable instead --- .../DisplayManager/DisplayManager.cs | 4 +- .../IGL_TK.cs | 67 +++++++++++++------ .../RetroShader.cs | 6 +- .../BizHawk.Bizware.BizwareGL/GuiRenderer.cs | 6 +- Bizware/BizHawk.Bizware.BizwareGL/IGL.cs | 6 +- Bizware/BizHawk.Bizware.BizwareGL/Pipeline.cs | 12 +--- Bizware/BizHawk.Bizware.BizwareGL/Shader.cs | 4 +- 7 files changed, 64 insertions(+), 41 deletions(-) diff --git a/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs b/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs index c5e0797dbb..eafcc8f115 100644 --- a/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs +++ b/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs @@ -121,7 +121,7 @@ namespace BizHawk.Client.EmuHawk //TargetScanlineFilterIntensity //apply filter chain (currently, over-simplified) Texture2d currentTexture = videoTexture; - if (Global.Config.TargetDisplayFilter == 1) + if (Global.Config.TargetDisplayFilter == 1 && RetroShader_Hq2x.Pipeline.Available) { var rt = Video2xFrugalizer.Get(videoTexture.IntWidth*2,videoTexture.IntHeight*2); rt.Bind(); @@ -129,7 +129,7 @@ namespace BizHawk.Client.EmuHawk RetroShader_Hq2x.Run(videoTexture, videoTexture.Size, outSize, true); currentTexture = rt.Texture2d; } - if (Global.Config.TargetDisplayFilter == 2) + if (Global.Config.TargetDisplayFilter == 2 && RetroShader_BizScanlines.Pipeline.Available) { var rt = Video2xFrugalizer.Get(videoTexture.IntWidth*2,videoTexture.IntHeight*2); rt.Bind(); diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs index cccd52ef95..d06a98a6ec 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs @@ -92,18 +92,14 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK public IntPtr GetEmptyHandle() { return new IntPtr(0); } public IntPtr GetEmptyUniformHandle() { return new IntPtr(-1); } - public Shader CreateFragmentShader(string source) + + public Shader CreateFragmentShader(string source, bool required) { - int sid = GL.CreateShader(ShaderType.FragmentShader); - CompileShaderSimple(sid,source); - return new Shader(this,new IntPtr(sid)); + return CreateShader(ShaderType.FragmentShader, source, required); } - public Shader CreateVertexShader(string source) + public Shader CreateVertexShader(string source, bool required) { - int sid = GL.CreateShader(ShaderType.VertexShader); - CompileShaderSimple(sid, source); - - return new Shader(this, new IntPtr(sid)); + return CreateShader(ShaderType.VertexShader, source, required); } public void FreeShader(IntPtr shader) { GL.DeleteShader(shader.ToInt32()); } @@ -150,8 +146,10 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK public IBlendState BlendNone { get { return _rsBlendNone; } } public IBlendState BlendNormal { get { return _rsBlendNormal; } } - public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader) + public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required) { + bool success = true; + ErrorCode errcode; int pid = GL.CreateProgram(); GL.AttachShader(pid, vertexShader.Id.ToInt32()); @@ -167,14 +165,18 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK errcode = GL.GetError(); string resultLog = GL.GetProgramInfoLog(pid); - + if (errcode != ErrorCode.NoError) - throw new InvalidOperationException("Error creating pipeline (error returned from glLinkProgram): " + errcode + "\r\n\r\n" + resultLog); + if (required) + throw new InvalidOperationException("Error creating pipeline (error returned from glLinkProgram): " + errcode + "\r\n\r\n" + resultLog); + else success = false; int linkStatus; GL.GetProgram(pid, GetProgramParameterName.LinkStatus, out linkStatus); - if(linkStatus == 0) - throw new InvalidOperationException("Error creating pipeline (link status false returned from glLinkProgram): " + "\r\n\r\n" + resultLog); + if (linkStatus == 0) + if (required) + throw new InvalidOperationException("Error creating pipeline (link status false returned from glLinkProgram): " + "\r\n\r\n" + resultLog); + else success = false; //need to work on validation. apparently there are some weird caveats to glValidate which make it complicated and possibly excuses (barely) the intel drivers' dysfunctional operation //"A sampler points to a texture unit used by fixed function with an incompatible target" @@ -247,7 +249,10 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK //deactivate the program, so we dont accidentally use it GL.UseProgram(0); - return new Pipeline(this, new IntPtr(pid), vertexLayout, uniforms); + if (!vertexShader.Available) success = false; + if (!fragmentShader.Available) success = false; + + return new Pipeline(this, new IntPtr(pid), success, vertexLayout, uniforms); } public VertexLayout CreateVertexLayout() { return new VertexLayout(this, new IntPtr(0)); } @@ -269,6 +274,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK public void BindPipeline(Pipeline pipeline) { + if (!pipeline.Available) throw new InvalidOperationException("Attempt to bind unavailable pipeline"); sStatePendingVertexLayout = pipeline.VertexLayout; GL.UseProgram(pipeline.Id.ToInt32()); } @@ -488,15 +494,30 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK return glc; } - void CompileShaderSimple(int sid, string source) + Shader CreateShader(ShaderType type, string source, bool required) { + int sid = GL.CreateShader(type); + bool ok = CompileShaderSimple(sid,source, required); + if(!ok) + { + GL.DeleteShader(sid); + sid = 0; + } + return new Shader(this, new IntPtr(sid), ok); + } + + bool CompileShaderSimple(int sid, string source, bool required) + { + bool success = true; ErrorCode errcode; GL.ShaderSource(sid, source); errcode = GL.GetError(); if (errcode != ErrorCode.NoError) - throw new InvalidOperationException("Error compiling shader (ShaderSource)" + errcode); + if (required) + throw new InvalidOperationException("Error compiling shader (ShaderSource)" + errcode); + else success = false; GL.CompileShader(sid); errcode = GL.GetError(); @@ -504,13 +525,19 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK string resultLog = GL.GetShaderInfoLog(sid); if (errcode != ErrorCode.NoError) - throw new InvalidOperationException("Error compiling shader (CompileShader)" + errcode + "\r\n\r\n" + resultLog); + if (required) + throw new InvalidOperationException("Error compiling shader (CompileShader)" + errcode + "\r\n\r\n" + resultLog); + else success = false; int n; GL.GetShader(sid, ShaderParameter.CompileStatus, out n); - if(n==0) - throw new InvalidOperationException("Error compiling shader (CompileShader)" + "\r\n\r\n" + resultLog); + if (n == 0) + if (required) + throw new InvalidOperationException("Error compiling shader (CompileShader)" + "\r\n\r\n" + resultLog); + else success = false; + + return success; } void UnbindVertexAttributes() diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/RetroShader.cs b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/RetroShader.cs index 303ee9f172..e2f7381b91 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/RetroShader.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/RetroShader.cs @@ -25,9 +25,9 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK string vsSource = "#define VERTEX\r\n" + source; string psSource = "#define FRAGMENT\r\n" + source; - var vs = Owner.CreateVertexShader(vsSource); - var ps = Owner.CreateFragmentShader(psSource); - Pipeline = Owner.CreatePipeline(VertexLayout, vs, ps); + var vs = Owner.CreateVertexShader(vsSource, false); + var ps = Owner.CreateFragmentShader(psSource, false); + Pipeline = Owner.CreatePipeline(VertexLayout, vs, ps, false); } public void Dispose() diff --git a/Bizware/BizHawk.Bizware.BizwareGL/GuiRenderer.cs b/Bizware/BizHawk.Bizware.BizwareGL/GuiRenderer.cs index 45257965dd..607df40c4f 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/GuiRenderer.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL/GuiRenderer.cs @@ -28,9 +28,9 @@ namespace BizHawk.Bizware.BizwareGL _Projection = new MatrixStack(); _Modelview = new MatrixStack(); - var vs = Owner.CreateVertexShader(DefaultVertexShader); - var ps = Owner.CreateFragmentShader(DefaultPixelShader); - CurrPipeline = DefaultPipeline = Owner.CreatePipeline(VertexLayout, vs, ps); + var vs = Owner.CreateVertexShader(DefaultVertexShader,true); + var ps = Owner.CreateFragmentShader(DefaultPixelShader, true); + CurrPipeline = DefaultPipeline = Owner.CreatePipeline(VertexLayout, vs, ps, true); } public void Dispose() diff --git a/Bizware/BizHawk.Bizware.BizwareGL/IGL.cs b/Bizware/BizHawk.Bizware.BizwareGL/IGL.cs index 1c1df5c66b..f091b55ff6 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/IGL.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL/IGL.cs @@ -49,17 +49,17 @@ namespace BizHawk.Bizware.BizwareGL /// /// compile a fragment shader. This is the simplified method. A more complex method may be added later which will accept multiple sources and preprocessor definitions independently /// - Shader CreateFragmentShader(string source); + Shader CreateFragmentShader(string source, bool required); /// /// compile a vertex shader. This is the simplified method. A more complex method may be added later which will accept multiple sources and preprocessor definitions independently /// - Shader CreateVertexShader(string source); + Shader CreateVertexShader(string source, bool required); /// /// Creates a complete pipeline from the provided vertex and fragment shader handles /// - Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader); + Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required); /// /// Binds this pipeline as the current used for rendering diff --git a/Bizware/BizHawk.Bizware.BizwareGL/Pipeline.cs b/Bizware/BizHawk.Bizware.BizwareGL/Pipeline.cs index 47a5548943..70ae1a48c5 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/Pipeline.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL/Pipeline.cs @@ -8,11 +8,12 @@ namespace BizHawk.Bizware.BizwareGL /// public class Pipeline : IDisposable { - public Pipeline(IGL owner, IntPtr id, VertexLayout vertexLayout, IEnumerable uniforms) + public Pipeline(IGL owner, IntPtr id, bool available, VertexLayout vertexLayout, IEnumerable uniforms) { Owner = owner; Id = id; VertexLayout = vertexLayout; + Available = available; //create the uniforms from the info list we got UniformsDictionary = new SpecialWorkingDictionary(this); @@ -67,14 +68,7 @@ namespace BizHawk.Bizware.BizwareGL public IGL Owner { get; private set; } public IntPtr Id { get; private set; } public VertexLayout VertexLayout { get; private set; } - - ///// - ///// Makes the pipeline current - ///// - //public void BindData() - //{ - // Owner.BindPipeline(this); - //} + public bool Available { get; private set; } public void Dispose() { diff --git a/Bizware/BizHawk.Bizware.BizwareGL/Shader.cs b/Bizware/BizHawk.Bizware.BizwareGL/Shader.cs index 9dc8656a96..55a8998014 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/Shader.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL/Shader.cs @@ -8,15 +8,17 @@ namespace BizHawk.Bizware.BizwareGL /// public class Shader : IDisposable { - public Shader(IGL owner, IntPtr id) + public Shader(IGL owner, IntPtr id, bool available) { Owner = owner; Id = id; + Available = available; } public IGL Owner { get; private set; } public IntPtr Id { get; private set; } public bool Disposed { get; private set; } + public bool Available { get; private set; } public void Dispose() {