mesa: Handle GL_BACK correctly for ES 3.0 in glDrawBuffers().
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 18 Dec 2012 21:26:03 +0000 (13:26 -0800)
committerIan Romanick <ian.d.romanick@intel.com>
Tue, 15 Jan 2013 22:59:40 +0000 (14:59 -0800)
In ES 3.0, when calling glDrawBuffers() on the window system
framebuffer, the only valid targets are GL_NONE or GL_BACK.  Since there
is no stereo rendering in ES 3.0, this is a single buffer, unlike
desktop where it may be two (and thus isn't allowed).

For single-buffered configs, GL_BACK ironically means the front (and
only) buffer.  I'm not sure that it matters, however, as ES shouldn't
have front buffer rendering in the first place.

Fixes es3conform framebuffer_blit_coverage_default_draw_buffer_binding.

v2: Update GLES3 spec reference.

Signed-off-by: Anuj Phogat <anuj.phogat@gmail.com>
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> [v2]
Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> [v1]
src/mesa/main/buffers.c

index 3dcd46f01807b5b63e4065cab0e8fbf39cbea901..b4f324c6c91eb39f499c2bf60277d2b7c79a1501 100644 (file)
@@ -94,7 +94,7 @@ supported_buffer_bitmask(const struct gl_context *ctx,
  * GL_FRONT_AND_BACK), return the corresponding bitmask of BUFFER_BIT_* flags.
  */
 static GLbitfield
-draw_buffer_enum_to_bitmask(GLenum buffer)
+draw_buffer_enum_to_bitmask(const struct gl_context *ctx, GLenum buffer)
 {
    switch (buffer) {
       case GL_NONE:
@@ -102,6 +102,21 @@ draw_buffer_enum_to_bitmask(GLenum buffer)
       case GL_FRONT:
          return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT;
       case GL_BACK:
+         if (_mesa_is_gles3(ctx)) {
+            /* Page 181 (page 192 of the PDF) in section 4.2.1 of the OpenGL
+             * ES 3.0.1 specification says:
+             *
+             *     "When draw buffer zero is BACK, color values are written
+             *     into the sole buffer for single-buffered contexts, or into
+             *     the back buffer for double-buffered contexts."
+             *
+             * Since there is no stereo rendering in ES 3.0, only return the
+             * LEFT bits.  This also satisfies the "n must be 1" requirement.
+             */
+            if (ctx->DrawBuffer->Visual.doubleBufferMode)
+               return BUFFER_BIT_BACK_LEFT;
+            return BUFFER_BIT_FRONT_LEFT;
+         }
          return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;
       case GL_RIGHT:
          return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT;
@@ -241,7 +256,7 @@ _mesa_DrawBuffer(GLenum buffer)
    else {
       const GLbitfield supportedMask
          = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
-      destMask = draw_buffer_enum_to_bitmask(buffer);
+      destMask = draw_buffer_enum_to_bitmask(ctx, buffer);
       if (destMask == BAD_MASK) {
          /* totally bogus buffer */
          _mesa_error(ctx, GL_INVALID_ENUM,
@@ -321,7 +336,7 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
             return;
          }
 
-         destMask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
+         destMask[output] = draw_buffer_enum_to_bitmask(ctx, buffers[output]);
 
          /* From the OpenGL 3.0 specification, page 258:
           * "Each buffer listed in bufs must be one of the values from tables
@@ -451,7 +466,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
       const GLbitfield supportedMask = supported_buffer_bitmask(ctx, fb);
       GLuint output;
       for (output = 0; output < n; output++) {
-         mask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
+         mask[output] = draw_buffer_enum_to_bitmask(ctx, buffers[output]);
          ASSERT(mask[output] != BAD_MASK);
          mask[output] &= supportedMask;
       }