st/mesa: Fix handling of FBO.
authorChia-I Wu <olv@lunarg.com>
Sat, 13 Mar 2010 16:10:09 +0000 (00:10 +0800)
committerChia-I Wu <olv@lunarg.com>
Sun, 14 Mar 2010 02:23:51 +0000 (10:23 +0800)
FBOs are created by st_new_framebuffer and cannot be casted to
st_framebuffer.

src/mesa/state_tracker/st_manager.c

index 9475704121c8595c28ebb06b4594cd6725651f02..d04d72d48aa78a0664270558f923765f2c6d860f 100644 (file)
@@ -59,6 +59,16 @@ void st_destroy_context(struct st_context *st);
 void st_flush(struct st_context *st, uint pipeFlushFlags,
               struct pipe_fence_handle **fence);
 
+/**
+ * Note that this function may fail.
+ */
+static INLINE struct st_framebuffer *
+st_framebuffer(GLframebuffer *fb)
+{
+   /* FBO cannot be casted.  See st_new_framebuffer */
+   return (struct st_framebuffer *) ((fb && !fb->Name) ? fb : NULL);
+}
+
 /**
  * Map an attachment to a buffer index.
  */
@@ -464,9 +474,9 @@ st_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
    struct st_framebuffer *stfb;
 
    /* either draw or read winsys fb */
-   stfb = (struct st_framebuffer *) st->ctx->WinSysDrawBuffer;
+   stfb = st_framebuffer(st->ctx->WinSysDrawBuffer);
    if (!stfb || stfb->iface != stfbi)
-      stfb = (struct st_framebuffer *) st->ctx->WinSysReadBuffer;
+      stfb = st_framebuffer(st->ctx->WinSysReadBuffer);
    assert(stfb && stfb->iface == stfbi);
 
    p_atomic_set(&stfb->revalidate, TRUE);
@@ -606,7 +616,7 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
 
    if (st) {
       /* reuse/create the draw fb */
-      stfb = (struct st_framebuffer * ) st->ctx->DrawBuffer;
+      stfb = st_framebuffer(st->ctx->WinSysDrawBuffer);
       if (stfb && stfb->iface == stdrawi) {
          stdraw = NULL;
          st_framebuffer_reference(&stdraw, stfb);
@@ -616,7 +626,7 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
       }
 
       /* reuse/create the read fb */
-      stfb = (struct st_framebuffer * ) st->ctx->ReadBuffer;
+      stfb = st_framebuffer(st->ctx->WinSysReadBuffer);
       if (!stfb || stfb->iface != streadi)
          stfb = stdraw;
       if (stfb && stfb->iface == streadi) {
@@ -688,7 +698,7 @@ st_api_destroy(struct st_api *stapi)
 void
 st_manager_flush_frontbuffer(struct st_context *st)
 {
-   struct st_framebuffer *stfb = (struct st_framebuffer *) st->ctx->DrawBuffer;
+   struct st_framebuffer *stfb = st_framebuffer(st->ctx->DrawBuffer);
    struct st_renderbuffer *strb = NULL;
 
    if (stfb)
@@ -696,7 +706,7 @@ st_manager_flush_frontbuffer(struct st_context *st)
    if (!strb)
       return;
 
-   /* st_public.h or FBO */
+   /* st_public.h */
    if (!stfb->iface) {
       struct pipe_surface *front_surf = strb->surface;
       st->pipe->screen->flush_frontbuffer(st->pipe->screen,
@@ -713,12 +723,10 @@ st_manager_flush_frontbuffer(struct st_context *st)
 void
 st_manager_validate_framebuffers(struct st_context *st)
 {
-   struct st_framebuffer *stdraw, *stread;
+   struct st_framebuffer *stdraw = st_framebuffer(st->ctx->DrawBuffer);
+   struct st_framebuffer *stread = st_framebuffer(st->ctx->ReadBuffer);
 
-   stdraw = (struct st_framebuffer *) st->ctx->DrawBuffer;
-   stread = (struct st_framebuffer *) st->ctx->ReadBuffer;
-
-   /* st_public.h or FBO */
+   /* st_public.h */
    if ((stdraw && !stdraw->iface) || (stread && !stread->iface)) {
       struct pipe_screen *screen = st->pipe->screen;
       if (screen->update_buffer)
@@ -739,15 +747,15 @@ boolean
 st_manager_add_color_renderbuffer(struct st_context *st, GLframebuffer *fb,
                                   gl_buffer_index idx)
 {
-   struct st_framebuffer *stfb = (struct st_framebuffer *) fb;
+   struct st_framebuffer *stfb = st_framebuffer(fb);
+
+   /* FBO or st_public.h */
+   if (!stfb || !stfb->iface)
+      return FALSE;
 
    if (stfb->Base.Attachment[idx].Renderbuffer)
       return TRUE;
 
-   /* st_public.h or FBO */
-   if (!stfb->iface)
-      return FALSE;
-
    switch (idx) {
    case BUFFER_FRONT_LEFT:
    case BUFFER_BACK_LEFT: