From 6c0288655368f0decdf309ca4a90fc60cbc29378 Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Fri, 19 Sep 2014 01:24:32 +0200
Subject: New GLRendererQuirks.BuggyColorRenderbuffer: On Mesa 7.2 software,
 FBO color renderbuffer may cause a crash

Workaround crash caused by Mesa 7.2 software rendering
using color renderbuffer target in FBO.

If Mesa < 8.0 and software - or -
property 'jogl.fbo.force.nocolorrenderbuffer' is set,
set quirks:
	- GLRendererQuirks.BuggyColorRenderbuffer
	- GLRendererQuirks.NoFullFBOSupport (to disable MSAA)

GLFBODrawable always uses FBOMODE_USE_TEXTURE
if GLRendererQuirks.BuggyColorRenderbuffer is set.

+++

Crash Report:
  GNU C Library       : 2.13 stable
  OpenGL              : software
  Operating System    : Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.51-1 x86_64
  Processor ID        : x86 Family 6 Model 44 Stepping 2, GenuineIntel

Abnormal termination:
Segmentation violation

Register State (from fault):
  RAX = 00000000ff1818f0  RBX = 00000000beaf8afc
  RCX = 0000000000000004  RDX = 00007f85ed9c9010
  RSP = 00007f8252d24fd0  RBP = 00007f8252d25020
  RSI = 0000000017b9b330  RDI = 0000000015bca400

   R8 = 0000000000000000   R9 = 00007f81edcd3014
  R10 = 00007f823565f6ce  R11 = 00007f827bee49aa
  R12 = 0000000000001406  R13 = 0000000000000001
  R14 = 00000000154d5458  R15 = 00000000154d4f10

  RIP = 00007f823565f7bc  EFL = 0000000000010206

   CS = 0033   FS = 0000   GS = 0000

Stack Trace (from fault):
[  0] 0x00007f823565f7bc put_row_ubyte4 at /mesa/main/renderbuffer.c:665 (in /lib/libGL.so.1)
[  1] 0x00007f8235727239 _swrast_write_rgba_span at /mesa/swrast/s_span.c:1450 (in /lib/libGL.so.1)
[  2] 0x00007f823574b071 smooth_rgba_triangle at /mesa/swrast/s_tritemp.h:862 (in /lib/libGL.so.1)
[  3] 0x00007f82357155f0 _swrast_Triangle at /mesa/swrast/s_context.c:692 (in /lib/libGL.so.1)
[  4] 0x00007f8235771780 triangle_offset_twoside_rgba at /mesa/swrast_setup/ss_tritmp.h:188 (in /lib/libGL.so.1)
[  5] 0x00007f82356d2cea _tnl_render_poly_elts at /mesa/tnl/t_vb_rendertmp.h:313 (in /lib/libGL.so.1)
[  6] 0x00007f82356d335e _tnl_RenderClippedPolygon at /mesa/tnl/t_vb_render.c:244 (in /lib/libGL.so.1)
[  7] 0x00007f82356c9313 clip_tri_4 at /mesa/tnl/t_vb_cliptmp.h:230 (in /lib/libGL.so.1)
[  8] 0x00007f82356cd026 clip_render_triangles_verts at /mesa/tnl/t_vb_rendertmp.h:163 (in /lib/libGL.so.1)
[  9] 0x00007f82356d37d9 run_render at /mesa/tnl/t_vb_render.c:320 (in /lib/libGL.so.1)
[ 10] 0x00007f82356c2436 _tnl_run_pipeline at /mesa/tnl/t_pipeline.c:158 (in /lib/libGL.so.1)
[ 11] 0x00007f82356c37da _tnl_draw_prims at /mesa/tnl/t_draw.c:402 (in /lib/libGL.so.1)
[ 12] 0x00007f82356b673a vbo_exec_DrawArrays at /mesa/vbo/vbo_exec_array.c:263 (in /lib/libGL.so.1)
[ 13] 0x00007f823583e5b0 glDrawArrays at /mesa/glapi/glapitemp.h:1645 (in /lib/libGL.so.1)

+++
---
 .../com/jogamp/opengl/GLRendererQuirks.java        | 33 ++++++++++++++++++++--
 src/jogl/classes/javax/media/opengl/GLContext.java |  1 +
 .../classes/javax/media/opengl/GLFBODrawable.java  |  5 ++++
 src/jogl/classes/jogamp/opengl/GLContextImpl.java  | 22 +++++++++++++--
 .../classes/jogamp/opengl/GLFBODrawableImpl.java   |  9 +++++-
 5 files changed, 65 insertions(+), 5 deletions(-)

(limited to 'src/jogl/classes')

diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
index f6e671c88..f81d2f2d0 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -191,7 +191,12 @@ public class GLRendererQuirks {
      *       <li>GL_RENDERER: <i>Gallium 0.4 on SVGA3D; build: RELEASE;</i> </li>
      *     </ul></li>
      * </ul>
+     * <p>
+     * Also enabled via {@link #BuggyColorRenderbuffer}.
+     * </p>
+     * <p>
      * Quirk can also be enabled via property: <code>jogl.fbo.force.min</code>.
+     * </p>
      */
     public static final int NoFullFBOSupport = 11;
 
@@ -312,8 +317,32 @@ public class GLRendererQuirks {
      */
     public static final int NoMultiSamplingBuffers  = 17;
 
+    /**
+     * With certain drivers no reliable FBO color renderbuffer target
+     * is available, read <i>a crash</i> may occur.
+     * <p>
+     * Appears on:
+     * <ul>
+     *   <li>GL_VENDOR       Brian Paul</li>
+     *   <li>GL_RENDERER     Mesa X11</li>
+     *   <li>GL_VERSION      2.1 Mesa 7.2</li>
+     * </ul>
+     * TODO: We have to determine the exact version range, i.e. not adding the quirk with fixed driver version!
+     * </p>
+     * <p>
+     * Note: Also enables {@link #NoFullFBOSupport}.
+     * </p>
+     * <p>
+     * Note: GLFBODrawable always uses texture attachments if set.
+     * </p>
+     * <p>
+     * Quirk can also be enabled via property: <code>jogl.fbo.force.nocolorrenderbuffer</code>.
+     * </p>
+     */
+    public static final int BuggyColorRenderbuffer  = 18;
+
     /** Number of quirks known. */
-    public static final int COUNT = 18;
+    public static final int COUNT = 19;
 
     private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval",
                                                           "NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard",
@@ -321,7 +350,7 @@ public class GLRendererQuirks {
                                                           "NeedCurrCtx4ARBPixFmtQueries", "NeedCurrCtx4ARBCreateContext",
                                                           "NoFullFBOSupport", "GLSLNonCompliant", "GL4NeedsGL3Request",
                                                           "GLSharedContextBuggy", "GLES3ViaEGLES2Config", "SingletonEGLDisplayOnly",
-                                                          "NoMultiSamplingBuffers"
+                                                          "NoMultiSamplingBuffers", "BuggyColorRenderbuffer"
                                                         };
 
     private static final IdentityHashMap<String, GLRendererQuirks> stickyDeviceQuirks = new IdentityHashMap<String, GLRendererQuirks>();
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 6334c35d0..e2498e6f1 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -108,6 +108,7 @@ public abstract class GLContext {
 
   protected static final boolean FORCE_NO_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.none", true);
   protected static final boolean FORCE_MIN_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.min", true);
+  protected static final boolean FORCE_NO_COLOR_RENDERBUFFER = Debug.isPropertyDefined("jogl.fbo.force.nocolorrenderbuffer", true);
 
   /** Reflects property jogl.debug.DebugGL. If true, the debug pipeline is enabled at context creation. */
   public static final boolean DEBUG_GL = Debug.isPropertyDefined("jogl.debug.DebugGL", true);
diff --git a/src/jogl/classes/javax/media/opengl/GLFBODrawable.java b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
index f423e0ee4..e98e5cbd5 100644
--- a/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
@@ -34,6 +34,7 @@ import com.jogamp.opengl.FBObject;
 import com.jogamp.opengl.FBObject.Colorbuffer;
 import com.jogamp.opengl.FBObject.ColorAttachment;
 import com.jogamp.opengl.FBObject.TextureAttachment;
+import com.jogamp.opengl.GLRendererQuirks;
 
 /**
  * Platform-independent {@link GLDrawable} specialization,
@@ -95,6 +96,10 @@ public interface GLFBODrawable extends GLDrawable {
      * <p>
      * See {@link #FBOMODE_DEFAULT} values.
      * </p>
+     * <p>
+     * If {@link GLRendererQuirks#BuggyColorRenderbuffer} is set,
+     * {@link #FBOMODE_USE_TEXTURE} is always added at initialization.
+     * </p>
      *
      * @param modeBits custom FBO mode bits like {@link #FBOMODE_USE_TEXTURE} and {@link #FBOMODE_USE_DEPTH}.
      * @throws IllegalStateException if the underlying FBO is already {@link #isInitialized()}.
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 1dac79516..6239103da 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -1921,6 +1921,15 @@ public abstract class GLContextImpl extends GLContext {
                 System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer);
             }
             quirks.addQuirk( quirk );
+        } else {
+            // software
+            if( vendorVersion.compareTo(mesaSafeFBOVersion) < 0 ) { // FIXME: Is it fixed in >= 8.0.0 ?
+                final int quirk = GLRendererQuirks.BuggyColorRenderbuffer;
+                if(DEBUG) {
+                    System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer + " / Mesa-Version "+vendorVersion);
+                }
+                quirks.addQuirk( quirk );
+            }
         }
         if (compatCtx && (major > 3 || (major == 3 && minor >= 1))) {
             // FIXME: Apply vendor version constraints!
@@ -1963,13 +1972,22 @@ public abstract class GLContextImpl extends GLContext {
     //
     // Property related quirks
     //
-    if( FORCE_MIN_FBO_SUPPORT ) {
-        final int quirk = GLRendererQuirks.NoFullFBOSupport;
+    if( FORCE_NO_COLOR_RENDERBUFFER ) {
+        final int quirk = GLRendererQuirks.BuggyColorRenderbuffer;
         if(DEBUG) {
             System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: property");
         }
         quirks.addQuirk( quirk );
     }
+    if( FORCE_MIN_FBO_SUPPORT || quirks.exist(GLRendererQuirks.BuggyColorRenderbuffer) ) {
+        final int quirk = GLRendererQuirks.NoFullFBOSupport;
+        if(DEBUG) {
+            final String causeProps = FORCE_MIN_FBO_SUPPORT ? "property, " : "";
+            final String causeQuirk = quirks.exist(GLRendererQuirks.BuggyColorRenderbuffer) ? "BuggyColorRenderbuffer" : "";
+            System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: "+causeProps+causeQuirk);
+        }
+        quirks.addQuirk( quirk );
+    }
 
     if(DEBUG) {
         System.err.println("Quirks local.0: "+quirks);
diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
index 0d871017e..f3954b7b6 100644
--- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -15,6 +15,7 @@ import com.jogamp.common.util.PropertyAccess;
 import com.jogamp.common.util.VersionUtil;
 import com.jogamp.nativewindow.MutableGraphicsConfiguration;
 import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.GLRendererQuirks;
 import com.jogamp.opengl.FBObject.Attachment;
 import com.jogamp.opengl.FBObject.Colorbuffer;
 import com.jogamp.opengl.FBObject.TextureAttachment;
@@ -44,7 +45,7 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
     static {
         Debug.initSingleton();
         DEBUG = GLDrawableImpl.DEBUG || Debug.debug("FBObject");
-        DEBUG_SWAP = DEBUG || PropertyAccess.isPropertyDefined("jogl.debug.FBObject.Swap", true);
+        DEBUG_SWAP = PropertyAccess.isPropertyDefined("jogl.debug.FBObject.Swap", true);
     }
 
     private final GLDrawableImpl parent;
@@ -198,6 +199,12 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
             fboIBack = 0;                // head
             fboIFront = fbos.length - 1; // tail
 
+            if( 0 == ( FBOMODE_USE_TEXTURE & fboModeBits ) &&
+                gl.getContext().hasRendererQuirk(GLRendererQuirks.BuggyColorRenderbuffer) ) {
+                // GLRendererQuirks.BuggyColorRenderbuffer also disables MSAA, i.e. full FBO support
+                fboModeBits |= FBOMODE_USE_TEXTURE;
+            }
+
             final boolean useTexture = 0 != ( FBOMODE_USE_TEXTURE & fboModeBits );
             final boolean useDepth   = 0 != ( FBOMODE_USE_DEPTH   & fboModeBits );
             final boolean useStencil = chosenFBOCaps.getStencilBits() > 0;
-- 
cgit v1.2.3