Khronos Public Bugzilla
Bug 256 - glClearBuffer + default framebuffer needs clarifying/fixing
glClearBuffer + default framebuffer needs clarifying/fixing
Status: RESOLVED FIXED
Product: OpenGL
Classification: Unclassified
Component: API Specification
3.2
PC Windows
: P3 major
: ---
Assigned To: Jon Leech
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2010-02-14 12:37 PST by Dan Bartlett
Modified: 2013-07-12 02:10 PDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dan Bartlett 2010-02-14 12:37:33 PST
In section 4.2.2 of the OpenGL 3.2 spec, it states:

"Individual buffers of the currently bound draw framebuffer may be cleared with
the command:
  void ClearBuffer{if ui}v( enum buffer, int drawbuffer, const T *value );
where buffer and drawbuffer identify a buffer to clear, and value specifies the value or values to clear it to.

If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is specified by
passing i as the parameter drawbuffer, and value points to a four-element vector
specifying the R, G, B, and A color to clear that draw buffer to. If the draw
buffer is one of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying
multiple buffers, each selected buffer is cleared to the same value."

This should probably mention that FRONT_LEFT, BACK_LEFT, FRONT_RIGHT, BACK_RIGHT, FRONT, BACK, LEFT, RIGHT, FRONT_AND_BACK, (NONE?) are (I assume) valid when the default framebuffer is bound, and that when an FBO is bound then passing i as the drawbuffer parameter refers to DRAW_BUFFERi.

and then later:

"ClearBuffer generates an INVALID_VALUE error if buffer is COLOR and drawbuffer
is less than zero, or greater than the value of MAX_DRAW_BUFFERS minus
one; or if buffer is DEPTH, STENCIL, or DEPTH_STENCIL and drawbuffer is not
zero."

This should also probably mention the allowed values when default framebuffer is bound.

Currently NVidia drivers return "GL_INVALID_VALUE" if you try the following code:

 glBindFrameBuffer(GL_FRAMEBUFFER, 0);
// glClearBufferfv(GL_COLOR, GL_BACK_LEFT, @ClearColor);
 glClearBufferfv(GL_COLOR, GL_LEFT, @ClearColor);
// glClearBufferfv(GL_COLOR, GL_BACK, @ClearColor);

but it will allow:

 glBindFrameBuffer(GL_FRAMEBUFFER, 0);
 glClearBufferfv(GL_COLOR, 0, @ClearColor);

which seems to be wrong.
Comment 1 Jon Leech 2013-07-11 00:54:08 PDT
(In reply to comment #0)
> In section 4.2.2 of the OpenGL 3.2 spec, it states:
> 
> "Individual buffers of the currently bound draw framebuffer may be cleared
> with
> the command:
>   void ClearBuffer{if ui}v( enum buffer, int drawbuffer, const T *value );
> where buffer and drawbuffer identify a buffer to clear, and value specifies
> the value or values to clear it to.
> 
> If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is specified by
> passing i as the parameter drawbuffer, and value points to a four-element
> vector
> specifying the R, G, B, and A color to clear that draw buffer to. If the draw
> buffer is one of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying
> multiple buffers, each selected buffer is cleared to the same value."

Sorry to delay so long in responding to this. If I'm understanding your
issue properly, you're suggesting that parameters like FRONT and BACK
are valid as the <drawbuffer> parameter of ClearBuffer*, which is not
the case - the only buffers you can identify to these commands are
one of the draw buffers for color clears, or depth, stencil, and
depth+stencil.

> This should probably mention that FRONT_LEFT, BACK_LEFT, FRONT_RIGHT,
> BACK_RIGHT, FRONT, BACK, LEFT, RIGHT, FRONT_AND_BACK, (NONE?) are (I assume)
> valid when the default framebuffer is bound, and that when an FBO is bound
> then passing i as the drawbuffer parameter refers to DRAW_BUFFERi.

The intent certainly is that whatever buffers are identified by the
value of DRAW_BUFFERi are cleared by ClearBuffer* with drawbuffer=i.
I will ask if the ARB minds a clarification in this regard for the
default framebuffer. We may also be missing an error for the case
when NONE is bound to DRAW_BUFFERi and ClearBuffer is called for that
draw buffer (I'd be inclined to treat that as silently ignored
myself, but I'll see what the ARB says and what implementations
actually do with it today).

> Currently NVidia drivers return "GL_INVALID_VALUE" if you try the following
> code:
> 
>  glBindFrameBuffer(GL_FRAMEBUFFER, 0);
> // glClearBufferfv(GL_COLOR, GL_BACK_LEFT, @ClearColor);
>  glClearBufferfv(GL_COLOR, GL_LEFT, @ClearColor);
> // glClearBufferfv(GL_COLOR, GL_BACK, @ClearColor);

That's as expected.

> but it will allow:
> 
>  glBindFrameBuffer(GL_FRAMEBUFFER, 0);
>  glClearBufferfv(GL_COLOR, 0, @ClearColor);
> 
> which seems to be wrong.

Again, will check with the IHVs.
Comment 2 Jon Leech 2013-07-11 16:01:16 PDT
The next spec update will clarify that the value of the selected
draw buffer may be any of the legal values to DrawBuffer(s), and
that the corresponding buffer(s) are all cleared to the same value.
It will also specify that if the value of the selected draw buffer
is NONE, ClearBuffer* has no effect (but does not generate an error).

> but it will allow:
> 
>  glBindFrameBuffer(GL_FRAMEBUFFER, 0);
>  glClearBufferfv(GL_COLOR, 0, @ClearColor);
> 
> which seems to be wrong.

Unless I'm missing something subtle, you are binding the draw framebuffer
to the default window-system provided framebuffer, then clearing
draw buffer zero of that framebuffer. There's nothing obviously
wrong in this example.
Comment 3 Dan Bartlett 2013-07-11 21:09:51 PDT
(In reply to comment #2)
> The next spec update will clarify that the value of the selected
> draw buffer may be any of the legal values to DrawBuffer(s), and
> that the corresponding buffer(s) are all cleared to the same value.
> It will also specify that if the value of the selected draw buffer
> is NONE, ClearBuffer* has no effect (but does not generate an error).
> 

Okay thanks, when I (mis)read the text I took it to mean the value of the argument "drawbuffer" was used to identify the buffer directly, rather than the draw buffer specified with DrawBuffer(s).

As I understand it now, this means the only valid values are:
(GL_COLOR, 0..MAX_DRAW_BUFFERS-1, ...)
(GL_DEPTH, 0, ...)
(GL_STENCIL, 0, ...)
(GL_DEPTH_STENCIL, 0, ...)
And to use FRONT, BACK, LEFT, RIGHT, and FRONT_AND_BACK with glClearBuffer()/glColorMaski() then you would need to use glDrawBuffer() rather than glDrawBuffers(), so there wouldn't be any real benefit of using these functions rather than glClear()/glColorMask() for these constants.

2 related issues:

1) If those are the only values accepted, it means the man page(s) for glClearBuffer ( http://www.opengl.org/sdk/docs/man3/xhtml/glClearBuffer.xml ) needs fixing as it mentions invalid values accepted for "buffer".

2) There's also a minor typo in the OpenGL 4.2 spec related to glColorMaski: The text for glColorMaski says "An INVALID_VALUE error is generated if index is greater than the value of MAX_DRAW_BUFFERS minus one." but the argument name is "buf".
Comment 4 Jon Leech 2013-07-12 02:10:49 PDT
(In reply to comment #3)
> As I understand it now, this means the only valid values are:
> (GL_COLOR, 0..MAX_DRAW_BUFFERS-1, ...)
> (GL_DEPTH, 0, ...)
> (GL_STENCIL, 0, ...)
> (GL_DEPTH_STENCIL, 0, ...)

Right.

> And to use FRONT, BACK, LEFT, RIGHT, and FRONT_AND_BACK with
> glClearBuffer()/glColorMaski() then you would need to use glDrawBuffer()
> rather than glDrawBuffers(), so there wouldn't be any real benefit of using
> these functions rather than glClear()/glColorMask() for these constants.

Most of the point of ClearBuffer* was to avoid the twists the original
NVIDIA integer texture extensions went through to use Clear() with
integer buffers, which involved some hairy dynamic type reinterpretation
of the clear color state which some of us found objectionable. And most
of the applications of integer renderbuffers are going to be to FBOs.
So yes, there may not be a lot of applicability of ClearBuffer to
the default framebuffer, but we didn't want to restrict it to just FBOs,
either.

> 2 related issues:
> 
> 1) If those are the only values accepted, it means the man page(s) for
> glClearBuffer ( http://www.opengl.org/sdk/docs/man3/xhtml/glClearBuffer.xml
> ) needs fixing as it mentions invalid values accepted for "buffer".

I've asked Graham Sellers to fix this the next time he updates the man pages.

> 2) There's also a minor typo in the OpenGL 4.2 spec related to glColorMaski:
> The text for glColorMaski says "An INVALID_VALUE error is generated if index
> is greater than the value of MAX_DRAW_BUFFERS minus one." but the argument
> name is "buf".

This will be fixed in the next public spec update. Thanks!