[Mesa-dev] Conflicts between OES/EXT/ARB_framebuffer_object and GL3.0/GLES2
Chad Versace
chad.versace at linux.intel.com
Wed May 2 18:32:01 PDT 2012
Mesa has problems in the way it implements glBindFramebuffer and
glBindFramebufferEXT due to both being implemented by an overloaded
_mesa_BindFramebufferEXT. This problem causes an Android app [1] to crash,
and I want your opinion on how we should fix it.
The problem is that in the five specs in the subject line, the specified
behavior of glBindFramebuffer falls into two incompatible categories.
Mesa implements the wrong behavior for OES_fbo, EXT_fbo, and GLES2 when
ARB_fbo is internally enabled.
[1] Pauli and Charles (CC'd) have more details about this crash, including an
apitrace, if you're curious.
Behavior in Category A: ARB_fbo and GL3.0
-----------------------------------------
The behavior in these specs can be summarized as:
1a. glBindFramebuffer may be called only on fb names produced by
glGenFramebuffers.
2a. glBindFramebuffer may not be called on an fb name previously deleted
with glDeleteFramebuffers.
Below is the pertinent quote from the ARB_fbo spec. The language in the GL 3.0
spec is nearly identical.
A framebuffer object is created by binding
a name returned by GenFramebuffers (see below) to
DRAW_FRAMEBUFFER or READ_FRAMEBUFFER. The binding is
effected by calling
void BindFramebuffer(enum target, uint framebuffer);
[...]
BindFramebuffer fails and an INVALID_OPERATION error is generated if
<framebuffer> is not zero or a name returned from a previous call to
GenFramebuffers, or if such a name has since been deleted with
DeleteFramebuffers.
Behavior in Category B: EXT/OES_fbo and GLES2
----------------------------------------------
The behavior in these specs can be summarized as below. This behavior is
incompatible with points 1a and 2a.
1b. glBindFramebuffer may be called on any unused fb name.
2b. glBindFramebuffers may be called on an fb name previously deleted with
glDeleteFramebuffers because, according to these specs, deletion marks
a name as unused.
Below is the pertininent quote from the EXT_fbo spec. The language of the GLES
2 spec is nearly identical, but without the EXT suffix. The OES_fbo spec
refers to the EXT_fbo spec.
The namespace for framebuffer objects is the unsigned integers, with
zero reserved by the GL to refer to the default framebuffer. A
framebuffer object is created by binding an unused name to the
target FRAMEBUFFER_EXT. The binding is effected by calling
void BindFramebufferEXT(enum target, uint framebuffer);
[...]
Framebuffer objects are deleted by calling
void DeleteFramebuffersEXT(sizei n, uint *framebuffers);
<framebuffers> contains <n> names of framebuffer objects to be
deleted. After a framebuffer object is deleted, [...],
and its name is again unused.
The Crashing App
----------------
We have an Android app that does this:
glGenFramebuffers(1, &fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
// render render render...
glDeleteFramebuffers(1, &fb);
// go do other stuff...
glBindFramebuffer(GL_FRAMEBUFFER, fb);
// This bind unexpectedly failed, and the app panics.
The call to glBindFramebuffer fails because, in GLES1 and GLES2 contexts, the
Intel drivers internally enables both ARB_fbo and EXT_fbo. In
_mesa_BindFramebufferEXT, the ARB_fbo behavior wins.
Solutions for core Mesa
-----------------------
As for fixing _mesa_BindFramebufferEXT, I have two ideas.
1. Enforce in _mesa_BindFramebufferEXT that no more than one of ARB_fbo
and EXT_fbo is enabled, then clean up its validation logic. This is
a big hammer, and, if done right, can eliminate any ambiguities in behavior.
(FYI, if I understand the gallium code, the only drivers that currently
enable both are Intel, swrast, and OSMesa).
2. Create separate entry points:
- _mesa_BindFramebufferEXT, which implements
- glBindFramebufferEXT
- glBindFramebufferOES
- glBindFramebuffer in GLES2
- _mesa_BindFramebufferARB, which implements
- glBindFramebufferARB
- glBindFramebuffer in GL 3.x
Any opinions? (I slightly prefer 2).
Quick Solution for the Intel drivers
------------------------------------
A quick solution may be as simple as removing ARB_fbo from the Intel drivers'
GLES1/2 extension lists.
Do you see any problem in doing this?
Charles, you have experimented with disabling ARB_fbo from GLES1/2 contexts.
Did you observe any negative consequences?
- Chad
More information about the mesa-dev
mailing list