mesa/version.c: enable cull distance in version check.
[mesa.git] / src / mesa / main / fbobject.c
index 621f84f51ebd4466951d16fef24d74cc2c4cfae8..c81f5a083ebfd03083ceb7bc0f17c69d5584ff19 100644 (file)
@@ -1369,6 +1369,11 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
    bind_renderbuffer(target, renderbuffer, true);
 }
 
+/**
+ * ARB_framebuffer_no_attachment - Application passes requested param's
+ * here. NOTE: NumSamples requested need not be _NumSamples which is
+ * what the hw supports.
+ */
 static void
 framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb,
                        GLenum pname, GLint param, const char *func)
@@ -2471,7 +2476,6 @@ static void
 bind_framebuffer(GLenum target, GLuint framebuffer, bool allow_user_names)
 {
    struct gl_framebuffer *newDrawFb, *newReadFb;
-   struct gl_framebuffer *oldDrawFb, *oldReadFb;
    GLboolean bindReadBuf, bindDrawBuf;
    GET_CURRENT_CONTEXT(ctx);
 
@@ -2525,18 +2529,23 @@ bind_framebuffer(GLenum target, GLuint framebuffer, bool allow_user_names)
       newReadFb = ctx->WinSysReadBuffer;
    }
 
-   assert(newDrawFb);
-   assert(newDrawFb != &DummyFramebuffer);
+   _mesa_bind_framebuffers(ctx,
+                           bindDrawBuf ? newDrawFb : ctx->DrawBuffer,
+                           bindReadBuf ? newReadFb : ctx->ReadBuffer);
+}
 
-   /* save pointers to current/old framebuffers */
-   oldDrawFb = ctx->DrawBuffer;
-   oldReadFb = ctx->ReadBuffer;
+void
+_mesa_bind_framebuffers(struct gl_context *ctx,
+                        struct gl_framebuffer *newDrawFb,
+                        struct gl_framebuffer *newReadFb)
+{
+   struct gl_framebuffer *const oldDrawFb = ctx->DrawBuffer;
+   struct gl_framebuffer *const oldReadFb = ctx->ReadBuffer;
+   const bool bindDrawBuf = oldDrawFb != newDrawFb;
+   const bool bindReadBuf = oldReadFb != newReadFb;
 
-   /* check if really changing bindings */
-   if (oldDrawFb == newDrawFb)
-      bindDrawBuf = GL_FALSE;
-   if (oldReadFb == newReadFb)
-      bindReadBuf = GL_FALSE;
+   assert(newDrawFb);
+   assert(newDrawFb != &DummyFramebuffer);
 
    /*
     * OK, now bind the new Draw/Read framebuffers, if they're changing.
@@ -2573,7 +2582,12 @@ bind_framebuffer(GLenum target, GLuint framebuffer, bool allow_user_names)
    }
 
    if ((bindDrawBuf || bindReadBuf) && ctx->Driver.BindFramebuffer) {
-      ctx->Driver.BindFramebuffer(ctx, target, newDrawFb, newReadFb);
+      /* The few classic drivers that actually hook this function really only
+       * want to know if the draw framebuffer changed.
+       */
+      ctx->Driver.BindFramebuffer(ctx,
+                                  bindDrawBuf ? GL_FRAMEBUFFER : GL_READ_FRAMEBUFFER,
+                                  newDrawFb, newReadFb);
    }
 }
 
@@ -3571,8 +3585,22 @@ _mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
    const struct gl_renderbuffer_attachment *att;
    GLenum err;
 
-   /* The error differs in GL and GLES. */
-   err = _mesa_is_desktop_gl(ctx) ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
+   /* The error code for an attachment type of GL_NONE differs between APIs.
+    *
+    * From the ES 2.0.25 specification, page 127:
+    * "If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE, then
+    *  querying any other pname will generate INVALID_ENUM."
+    *
+    * From the OpenGL 3.0 specification, page 337, or identically,
+    * the OpenGL ES 3.0.4 specification, page 240:
+    *
+    * "If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE, no
+    *  framebuffer is bound to target.  In this case querying pname
+    *  FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero, and all other
+    *  queries will generate an INVALID_OPERATION error."
+    */
+   err = ctx->API == API_OPENGLES2 && ctx->Version < 30 ?
+      GL_INVALID_ENUM : GL_INVALID_OPERATION;
 
    if (_mesa_is_winsys_fbo(buffer)) {
       /* Page 126 (page 136 of the PDF) of the OpenGL ES 2.0.25 spec
@@ -3600,6 +3628,23 @@ _mesa_get_framebuffer_attachment_parameter(struct gl_context *ctx,
                      _mesa_enum_to_string(attachment));
          return;
       }
+
+      /* The specs are not clear about how to handle
+       * GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME with the default framebuffer,
+       * but dEQP-GLES3 expects an INVALID_ENUM error. This has also been
+       * discussed in:
+       *
+       * https://cvs.khronos.org/bugzilla/show_bug.cgi?id=12928#c1
+       * and https://bugs.freedesktop.org/show_bug.cgi?id=31947
+       */
+      if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
+         _mesa_error(ctx, GL_INVALID_ENUM,
+                     "%s(requesting GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME "
+                     "when GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is "
+                     "GL_FRAMEBUFFER_DEFAULT is not allowed)", caller);
+         return;
+      }
+
       /* the default / window-system FBO */
       att = _mesa_get_fb0_attachment(ctx, buffer, attachment);
    }
@@ -4161,7 +4206,8 @@ _mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
     */
    invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
                                   0, 0,
-                                  MAX_VIEWPORT_WIDTH, MAX_VIEWPORT_HEIGHT,
+                                  ctx->Const.MaxViewportWidth,
+                                  ctx->Const.MaxViewportHeight,
                                   "glInvalidateFramebuffer");
 }
 
@@ -4201,7 +4247,8 @@ _mesa_InvalidateNamedFramebufferData(GLuint framebuffer,
     */
    invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments,
                                   0, 0,
-                                  MAX_VIEWPORT_WIDTH, MAX_VIEWPORT_HEIGHT,
+                                  ctx->Const.MaxViewportWidth,
+                                  ctx->Const.MaxViewportHeight,
                                   "glInvalidateNamedFramebufferData");
 }