st/mesa: s/BUFFER_FRONT_LEFT/surfIndex/
[mesa.git] / src / mesa / state_tracker / st_framebuffer.c
index 13589151ba6946e353e38ceadd1e3a79b33b4631..0a91183f89dd3a0d75b04caf9dbc9eefb4196e98 100644 (file)
 #include "main/buffers.h"
 #include "main/context.h"
 #include "main/framebuffer.h"
-#include "main/matrix.h"
 #include "main/renderbuffer.h"
-#include "main/scissor.h"
-#include "main/viewport.h"
 #include "st_context.h"
 #include "st_cb_fbo.h"
 #include "st_public.h"
 #include "pipe/p_defines.h"
-#include "pipe/p_context.h"
+#include "util/u_inlines.h"
 
 
 struct st_framebuffer *
@@ -52,11 +49,12 @@ st_create_framebuffer( const __GLcontextModes *visual,
    struct st_framebuffer *stfb = ST_CALLOC_STRUCT(st_framebuffer);
    if (stfb) {
       int samples = st_get_msaa();
+      int i;
 
       if (visual->sampleBuffers)
          samples = visual->samples;
 
-      _mesa_initialize_framebuffer(&stfb->Base, visual);
+      _mesa_initialize_window_framebuffer(&stfb->Base, visual);
 
       if (visual->doubleBufferMode) {
          struct gl_renderbuffer *rb
@@ -66,7 +64,7 @@ st_create_framebuffer( const __GLcontextModes *visual,
       else {
          /* Only allocate front buffer right now if we're single buffered.
           * If double-buffered, allocate front buffer on demand later.
-          * See check_create_front_buffers().
+          * See check_create_front_buffers() and st_set_framebuffer_surface().
           */
          struct gl_renderbuffer *rb
             = st_new_renderbuffer_fb(colorFormat, samples, FALSE);
@@ -119,6 +117,12 @@ st_create_framebuffer( const __GLcontextModes *visual,
          _mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb);
       }
 
+      for (i = 0; i < visual->numAuxBuffers; i++) {
+         struct gl_renderbuffer *aux
+            = st_new_renderbuffer_fb(colorFormat, 0, FALSE);
+         _mesa_add_renderbuffer(&stfb->Base, BUFFER_AUX0 + i, aux);
+      }
+
       stfb->Base.Initialized = GL_TRUE;
       stfb->InitWidth = width;
       stfb->InitHeight = height;
@@ -156,22 +160,39 @@ void st_unreference_framebuffer( struct st_framebuffer *stfb )
  * Set/replace a framebuffer surface.
  * The user of the state tracker can use this instead of
  * st_resize_framebuffer() to provide new surfaces when a window is resized.
+ * \param surfIndex  an ST_SURFACE_x index
  */
 void
 st_set_framebuffer_surface(struct st_framebuffer *stfb,
                            uint surfIndex, struct pipe_surface *surf)
 {
    GET_CURRENT_CONTEXT(ctx);
-   static const GLuint invalid_size = 9999999;
    struct st_renderbuffer *strb;
-   GLuint width, height, i;
+
+   /* sanity checks */
+   assert(ST_SURFACE_FRONT_LEFT == BUFFER_FRONT_LEFT);
+   assert(ST_SURFACE_BACK_LEFT == BUFFER_BACK_LEFT);
+   assert(ST_SURFACE_FRONT_RIGHT == BUFFER_FRONT_RIGHT);
+   assert(ST_SURFACE_BACK_RIGHT == BUFFER_BACK_RIGHT);
+   assert(ST_SURFACE_DEPTH == BUFFER_DEPTH);
 
    assert(surfIndex < BUFFER_COUNT);
 
    strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
 
-   /* fail */
-   if (!strb) return;
+   if (!strb) {
+      /* create new renderbuffer for this surface now */
+      const GLuint numSamples = stfb->Base.Visual.samples;
+      struct gl_renderbuffer *rb =
+         st_new_renderbuffer_fb(surf->format, numSamples, FALSE);
+      if (!rb) {
+         /* out of memory */
+         _mesa_warning(ctx, "Out of memory allocating renderbuffer");
+         return;
+      }
+      _mesa_add_renderbuffer(&stfb->Base, surfIndex, rb);
+      strb = st_renderbuffer(rb);
+   }
 
    /* replace the renderbuffer's surface/texture pointers */
    pipe_surface_reference( &strb->surface, surf );
@@ -182,39 +203,16 @@ st_set_framebuffer_surface(struct st_framebuffer *stfb,
        * But when we do, we need to start setting this dirty bit
        * to ensure the renderbuffer attachements are up-to-date
        * via update_framebuffer.
+       * Core Mesa's state validation will update the parent framebuffer's
+       * size info, etc.
        */
       ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER;
+      ctx->NewState |= _NEW_BUFFERS;
    }
 
    /* update renderbuffer's width/height */
    strb->Base.Width = surf->width;
    strb->Base.Height = surf->height;
-
-   /* Try to update the framebuffer's width/height from the renderbuffer
-    * sizes.  Before we start drawing, all the rbs _should_ be the same size.
-    */
-   width = height = invalid_size;
-   for (i = 0; i < BUFFER_COUNT; i++) {
-      if (stfb->Base.Attachment[i].Renderbuffer) {
-         if (width == invalid_size) {
-            width = stfb->Base.Attachment[i].Renderbuffer->Width;
-            height = stfb->Base.Attachment[i].Renderbuffer->Height;
-         }
-         else if (width != stfb->Base.Attachment[i].Renderbuffer->Width ||
-                  height != stfb->Base.Attachment[i].Renderbuffer->Height) {
-            /* inconsistant renderbuffer sizes, bail out */
-            return;
-         }
-      }
-   }
-
-   if (width != invalid_size) {
-      /* OK, the renderbuffers are of a consistant size, so update the
-       * parent framebuffer's size.
-       */
-      stfb->Base.Width = width;
-      stfb->Base.Height = height;
-   }
 }
 
 
@@ -280,7 +278,8 @@ st_notify_swapbuffers(struct st_framebuffer *stfb)
                PIPE_FLUSH_SWAPBUFFERS |
                PIPE_FLUSH_FRAME,
                 NULL );
-      ctx->st->frontbuffer_status = FRONT_STATUS_COPY_OF_BACK;
+      if (st_renderbuffer(stfb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer))
+         ctx->st->frontbuffer_status = FRONT_STATUS_COPY_OF_BACK;
    }
 }