Chris The Avatar's picture

Access Violation Error when generating frame buffers

One of my players is receiving an access violation error in the following set of code (This specific error has only been reported 1/200 or so people):

 if (GameInstance.GlobalScreen.DisplayDriverMajorVersion >= 3)
            {
                GL.GenFramebuffers(1, out fbo);
                GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, fbo);
 
                // assign texture to FBO
                GL.FramebufferTexture2D(FramebufferTarget.DrawFramebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, glTextureID, 0);
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); // d
            }
            else
            {
                GL.Ext.GenFramebuffers(1, out fbo); //<--------------------------- ERROR HERE
                GL.Ext.BindFramebuffer(FramebufferTarget.DrawFramebuffer, fbo);
 
                // assign texture to FBO
                GL.Ext.FramebufferTexture2D(FramebufferTarget.DrawFramebuffer, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, glTextureID, 0);
                GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); // d
            }

There are no open gl errors that are reported when calling the GLError function...

Here is the call stack:

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at OpenTK.Graphics.OpenGL.GL.Ext.GenFramebuffers(Int32 n, Int32& framebuffers)
at FRO.Client.Graphics.Surface.SetupFrameBuffer()
at FRO.Client.Game.Mapping.MapLightView..ctor(Map ParentMap)
at FRO.Client.Game.Mapping.Map..ctor()
at DreamHaven.Scripts.Menus.Windows.PrimaryGameMenu..ctor(Client ReceivedOn, UInt32 ID)

Am I not doing something correctly or any ideas on where to start. Unfortunately the user does not know his video card information...


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

His video card does not support the GL_EXT_framebuffer_object extension.

I have added a book page on How to check if an OpenGL extension is supported.

Using the entry points of an unsupported extension is an error and will cause undefined behavior. Possible results include an AccessViolationException (which is what you are getting here), silent failure (no crash, but the function does nothing) and driver/kernel-mode crashes.

Chris The Avatar's picture

So allow me to reitterate so I fully understand, Since his OGL driver version isnt >= 3 (which I already check) and his card doesnt support the extension method; basically his card doesnt support FBOs at all. Similar to the other framebuffer discussion we had last week... There isnt a good alternative in OpenTK to frame buffers (other than to implement the pbuffer we talked about before and while I want to tackle that dedicating time to do is a lower priority since it is affecting so few users).

I almost think Id be better off just falling back to not using a frame bfufer when they are not supported; Just the performance gains I got off them were astronomical.

the Fiddler's picture

Spot on.

It appears that there are some other solutions if FBO is not supported. I'm not sure if they are worth the effort involved, but take a look at this discussion on opengl.org: Render to texture, without FBO.

Edit: "just render to the back buffer then do glCopyTexSubImage2D". Huh, this might just be what you are looking for! :)

There is one last solution that is worth considering: use OpenGL ES 2.0 and ANGLE on these systems. ANGLE is an OpenGL ES emulator that uses Direct3D 9 internally, and it should support FBOs on all Direct3D 9-capable GPUs.

If you already have an OpenGL ES codepath for mobile devices, this might be the simplest way to improve compatibility with hardware that lacks good OpenGL drivers.

Chris The Avatar's picture

Hrmm however if I render to backbuffer in the middle of a frame and then copy it to a texture, doesn't that have potential to copy other artifacts from the back buffer to the texture? I would had assumed that would be called before to tell opengl you want to draw to a texture instead of the bb until you disable it.

the Fiddler's picture
Chris The Avatar wrote:

Hrmm however if I render to backbuffer in the middle of a frame and then copy it to a texture, doesn't that have potential to copy other artifacts from the back buffer to the texture? I would had assumed that would be called before to tell opengl you want to draw to a texture instead of the bb until you disable it.

Yes, that would cause artifacts. You would have to clear-render-copy the backbuffer before rendering anything else for the frame.

Other limitations would be lack of depth-copy support (for shadow mapping and SSAO) and undefined results for pixels that fail the ownership test (i.e. if your viewport is partially/fully covered by another window, or if your window is minimized.)

In short, the backbuffer trick cannot replace the FBO extension. It can only give some limited form of render-to-texture functionality on hardware that doesn't support FBOs. Whether you can use that depends on your specific application.

To sum up your options:

  1. Kindly inform the user that he should upgrade his drivers or hardware
  2. Add a non-FBO codepath with reduced functionality and/or speed
  3. Add a hack to fake FBO support on hardware that doesn't support it.
  4. Implement an OpenGL ES codepath and use ANGLE (as a bonus, you'd be able to reuse the same codepath for smartphones and microconsoles)

OpenTK gives you direct access to the OpenGL capabilities of the underlying hardware. If the hardware does not support a specific feature, there is nothing OpenTK can do about it (but you might be able to find a workaround.)

Chris The Avatar's picture

Thank you for taking the time to explain. I think I have a good understanding now, even if I cant use the glcopy now I could see that being useful for other purposes in the future (very educating).

Thanks

Chris