mesa: implement GL_MAX_VERTEX_ATTRIB_STRIDE
[mesa.git] / src / mesa / main / buffers.c
index 87848fb93796be2424dd8b1c16b0a3b0ffc5fcb2..8a0852c429c20d828a4128be344db3dabaa70783 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.1
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  */
 
 
@@ -60,7 +60,6 @@ supported_buffer_bitmask(const struct gl_context *ctx,
    if (_mesa_is_user_fbo(fb)) {
       /* A user-created renderbuffer */
       GLuint i;
-      ASSERT(ctx->Extensions.EXT_framebuffer_object);
       for (i = 0; i < ctx->Const.MaxColorAttachments; i++) {
          mask |= (BUFFER_BIT_COLOR0 << i);
       }
@@ -102,7 +101,7 @@ draw_buffer_enum_to_bitmask(const struct gl_context *ctx, GLenum buffer)
       case GL_FRONT:
          return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT;
       case GL_BACK:
-         if (_mesa_is_gles3(ctx)) {
+         if (_mesa_is_gles(ctx)) {
             /* Page 181 (page 192 of the PDF) in section 4.2.1 of the OpenGL
              * ES 3.0.1 specification says:
              *
@@ -112,6 +111,11 @@ draw_buffer_enum_to_bitmask(const struct gl_context *ctx, GLenum buffer)
              *
              * Since there is no stereo rendering in ES 3.0, only return the
              * LEFT bits.  This also satisfies the "n must be 1" requirement.
+             *
+             * We also do this for GLES 1 and 2 because those APIs have no
+             * concept of selecting the front and back buffer anyway and it's
+             * convenient to be able to maintain the magic behaviour of
+             * GL_BACK in that case.
              */
             if (ctx->DrawBuffer->Visual.doubleBufferMode)
                return BUFFER_BIT_BACK_LEFT;
@@ -226,8 +230,8 @@ read_buffer_enum_to_index(GLenum buffer)
  * \param buffer  buffer token such as GL_LEFT or GL_FRONT_AND_BACK, etc.
  *
  * Note that the behaviour of this function depends on whether the
- * current ctx->DrawBuffer is a window-system framebuffer (Name=0) or
- * a user-created framebuffer object (Name!=0).
+ * current ctx->DrawBuffer is a window-system framebuffer or a user-created
+ * framebuffer object.
  *   In the former case, we update the per-context ctx->Color.DrawBuffer
  *   state var _and_ the FB's ColorDrawBuffer state.
  *   In the later case, we update the FB's ColorDrawBuffer state only.
@@ -244,7 +248,8 @@ _mesa_DrawBuffer(GLenum buffer)
 {
    GLbitfield destMask;
    GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */
+
+   FLUSH_VERTICES(ctx, 0);
 
    if (MESA_VERBOSE & VERBOSE_API) {
       _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
@@ -301,7 +306,8 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
    GLbitfield usedBufferMask, supportedMask;
    GLbitfield destMask[MAX_DRAW_BUFFERS];
    GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   FLUSH_VERTICES(ctx, 0);
 
    /* Turns out n==0 is a valid input that should not produce an error.
     * The remaining code below correctly handles the n==0 case.
@@ -359,16 +365,18 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
             return;
          }         
 
-         /* From the OpenGL 3.0 specification, page 259:
+         /* From the OpenGL 4.0 specification, page 256:
           * "For both the default framebuffer and framebuffer objects, the
           *  constants FRONT, BACK, LEFT, RIGHT, and FRONT_AND_BACK are not
           *  valid in the bufs array passed to DrawBuffers, and will result in
-          *  the error INVALID_OPERATION.  This restriction is because these
+          *  the error INVALID_ENUM. This restriction is because these
           *  constants may themselves refer to multiple buffers, as shown in
           *  table 4.4."
+          *  Previous versions of the OpenGL specification say INVALID_OPERATION,
+          *  but the Khronos conformance tests expect INVALID_ENUM.
           */
          if (_mesa_bitcount(destMask[output]) > 1) {
-            _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB(buffer)");
+            _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
             return;
          }
 
@@ -486,10 +494,11 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
    }
 
    /*
-    * If n==1, destMask[0] may have up to four bits set.
+    * destMask[0] may have up to four bits set
+    * (ex: glDrawBuffer(GL_FRONT_AND_BACK)).
     * Otherwise, destMask[x] can only have one bit set.
     */
-   if (n == 1) {
+   if (n > 0 && _mesa_bitcount(destMask[0]) > 1) {
       GLuint count = 0, destMask0 = destMask[0];
       while (destMask0) {
          GLint bufIndex = ffs(destMask0) - 1;
@@ -558,16 +567,11 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
 void
 _mesa_update_draw_buffers(struct gl_context *ctx)
 {
-   GLenum buffers[MAX_DRAW_BUFFERS];
-   GLuint i;
-
    /* should be a window system FBO */
    assert(_mesa_is_winsys_fbo(ctx->DrawBuffer));
 
-   for (i = 0; i < ctx->Const.MaxDrawBuffers; i++)
-      buffers[i] = ctx->Color.DrawBuffer[i];
-
-   _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, buffers, NULL);
+   _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
+                     ctx->Color.DrawBuffer, NULL);
 }
 
 
@@ -609,7 +613,8 @@ _mesa_ReadBuffer(GLenum buffer)
    GLbitfield supportedMask;
    GLint srcBuffer;
    GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   FLUSH_VERTICES(ctx, 0);
 
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
@@ -642,7 +647,6 @@ _mesa_ReadBuffer(GLenum buffer)
    /* OK, all error checking has been completed now */
 
    _mesa_readbuffer(ctx, buffer, srcBuffer);
-   ctx->NewState |= _NEW_BUFFERS;
 
    /*
     * Call device driver function.