Merge commit 'origin/master' into i965g-restart
[mesa.git] / src / mesa / state_tracker / st_atom_framebuffer.c
index b32009c19bbe6e551d65462be68e9015a20b369c..8ca4335e3307f2e90bf541a197635e6f417a57af 100644 (file)
@@ -39,6 +39,8 @@
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
 #include "cso_cache/cso_context.h"
+#include "util/u_rect.h"
+#include "util/u_math.h"
 
 
 
@@ -63,8 +65,8 @@ update_renderbuffer_surface(struct st_context *st,
       GLuint level;
       /* find matching mipmap level size */
       for (level = 0; level <= texture->last_level; level++) {
-         if (texture->width[level] == rtt_width &&
-             texture->height[level] == rtt_height) {
+         if (u_minify(texture->width0, level) == rtt_width &&
+             u_minify(texture->height0, level) == rtt_height) {
 
             pipe_surface_reference(&strb->surface, NULL);
 
@@ -98,8 +100,6 @@ update_framebuffer_state( struct st_context *st )
    struct st_renderbuffer *strb;
    GLuint i;
 
-   memset(framebuffer, 0, sizeof(*framebuffer));
-
    framebuffer->width = fb->Width;
    framebuffer->height = fb->Height;
 
@@ -112,18 +112,28 @@ update_framebuffer_state( struct st_context *st )
    for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
       strb = st_renderbuffer(fb->_ColorDrawBuffers[i]);
 
-      /*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/
-      if (strb->rtt) {
-         /* rendering to a GL texture, may have to update surface */
-         update_renderbuffer_surface(st, strb);
-      }
+      if (strb) {
+         /*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/
+         if (strb->rtt) {
+            /* rendering to a GL texture, may have to update surface */
+            update_renderbuffer_surface(st, strb);
+         }
 
-      if (strb->surface) {
-         framebuffer->cbufs[framebuffer->nr_cbufs] = strb->surface;
-         framebuffer->nr_cbufs++;
+         if (strb->surface) {
+            pipe_surface_reference(&framebuffer->cbufs[framebuffer->nr_cbufs],
+                                   strb->surface);
+            framebuffer->nr_cbufs++;
+         }
+         strb->defined = GL_TRUE; /* we'll be drawing something */
       }
    }
+   for (i = framebuffer->nr_cbufs; i < PIPE_MAX_COLOR_BUFS; i++) {
+      pipe_surface_reference(&framebuffer->cbufs[i], NULL);
+   }
 
+   /*
+    * Depth/Stencil renderbuffer/surface.
+    */
    strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
    if (strb) {
       strb = st_renderbuffer(strb->Base.Wrapped);
@@ -131,16 +141,17 @@ update_framebuffer_state( struct st_context *st )
          /* rendering to a GL texture, may have to update surface */
          update_renderbuffer_surface(st, strb);
       }
-
-      framebuffer->zsbuf = strb->surface;
+      pipe_surface_reference(&framebuffer->zsbuf, strb->surface);
    }
    else {
       strb = st_renderbuffer(fb->Attachment[BUFFER_STENCIL].Renderbuffer);
       if (strb) {
          strb = st_renderbuffer(strb->Base.Wrapped);
          assert(strb->surface);
-         framebuffer->zsbuf = strb->surface;
+         pipe_surface_reference(&framebuffer->zsbuf, strb->surface);
       }
+      else
+         pipe_surface_reference(&framebuffer->zsbuf, NULL);
    }
 
    cso_set_framebuffer(st->cso_context, framebuffer);
@@ -153,10 +164,17 @@ update_framebuffer_state( struct st_context *st )
          (void) st_get_framebuffer_surface(stfb, ST_SURFACE_FRONT_LEFT, &surf_front);
          (void) st_get_framebuffer_surface(stfb, ST_SURFACE_BACK_LEFT, &surf_back);
 
-         st->pipe->surface_copy(st->pipe,
-                                surf_front, 0, 0,  /* dest */
-                                surf_back, 0, 0,   /* src */
-                                fb->Width, fb->Height);
+         if (st->pipe->surface_copy) {
+            st->pipe->surface_copy(st->pipe,
+                                   surf_front, 0, 0,  /* dest */
+                                   surf_back, 0, 0,   /* src */
+                                   fb->Width, fb->Height);
+         } else {
+            util_surface_copy(st->pipe, FALSE,
+                              surf_front, 0, 0,
+                              surf_back, 0, 0,
+                              fb->Width, fb->Height);
+         }
       }
       /* we're assuming we'll really draw to the front buffer */
       st->frontbuffer_status = FRONT_STATUS_DIRTY;