Merge branch 'mesa_7_5_branch'
authorJosé Fonseca <jfonseca@vmware.com>
Thu, 11 Jun 2009 15:34:56 +0000 (16:34 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Thu, 11 Jun 2009 15:34:56 +0000 (16:34 +0100)
Conflicts:
src/mesa/state_tracker/st_cb_fbo.c
src/mesa/state_tracker/st_framebuffer.c

1  2 
src/mesa/main/image.c
src/mesa/state_tracker/st_cb_fbo.c
src/mesa/state_tracker/st_cb_fbo.h
src/mesa/state_tracker/st_framebuffer.c

Simple merge
index c249f3b35781f12f6c4d3304aa1a24642d84b001,21ddf2fc7a28c59ebd2c0ecce4c18dad3976d5f6..ecdb988033cdff4e9e3529fffd761a38e87b9be7
@@@ -123,37 -98,60 +98,62 @@@ st_renderbuffer_alloc_storage(GLcontex
     /* init renderbuffer fields */
     strb->Base.Width  = width;
     strb->Base.Height = height;
-    init_renderbuffer_bits(strb, template.format);
+    init_renderbuffer_bits(strb, format);
  
-    /* Probably need dedicated flags for surface usage too: 
-     */
-    surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
-                     PIPE_BUFFER_USAGE_GPU_WRITE);
- #if 0
-                     PIPE_BUFFER_USAGE_CPU_READ |
-                     PIPE_BUFFER_USAGE_CPU_WRITE);
- #endif
 +   strb->defined = GL_FALSE;  /* undefined contents now */
 +
+    if(strb->software) {
+       struct pipe_format_block block;
+       size_t size;
+       
+       _mesa_free(strb->data);
+       assert(strb->format != PIPE_FORMAT_NONE);
+       pf_get_block(strb->format, &block);
+       
+       strb->stride = pf_get_stride(&block, width);
+       size = pf_get_2d_size(&block, strb->stride, height);
+       
+       strb->data = _mesa_malloc(size);
+       
+       return strb->data != NULL;
+    }
+    else {
+       struct pipe_texture template;
+       unsigned surface_usage;
+     
+       /* Free the old surface and texture
+        */
+       pipe_surface_reference( &strb->surface, NULL );
+       pipe_texture_reference( &strb->texture, NULL );
  
-    strb->texture = pipe->screen->texture_create( pipe->screen,
-                                                  &template );
+       /* Setup new texture template.
+        */
+       memset(&template, 0, sizeof(template));
+       template.target = PIPE_TEXTURE_2D;
+       template.format = format;
+       pf_get_block(format, &template.block);
+       template.width[0] = width;
+       template.height[0] = height;
+       template.depth[0] = 1;
+       template.last_level = 0;
+       template.nr_samples = rb->NumSamples;
+       if (pf_is_depth_stencil(format)) {
+          template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+       }
+       else {
+          template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+                                PIPE_TEXTURE_USAGE_RENDER_TARGET);
+       }
  
-    /* Special path for accum buffers.  
-     *
-     * Try a different surface format.  Since accum buffers are s/w
-     * only for now, the surface pixel format doesn't really matter,
-     * only that the buffer is large enough.
-     */
-    if (!strb->texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT) 
-    {
-       /* Actually, just setting this usage value should be sufficient
-        * to tell the driver to go ahead and allocate the buffer, even
-        * if HW doesn't support the format.
+       /* Probably need dedicated flags for surface usage too: 
         */
-       template.tex_usage = 0;
-       surface_usage = (PIPE_BUFFER_USAGE_CPU_READ |
+       surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
+                        PIPE_BUFFER_USAGE_GPU_WRITE);
+ #if 0
+                        PIPE_BUFFER_USAGE_CPU_READ |
                         PIPE_BUFFER_USAGE_CPU_WRITE);
+ #endif
  
        strb->texture = pipe->screen->texture_create( pipe->screen,
                                                      &template );
@@@ -464,134 -463,6 +465,134 @@@ st_validate_framebuffer(GLcontext *ctx
  }
  
  
-          front = st_new_renderbuffer_fb(colorFormat, samples);
 +/**
 + * Copy back color buffer to front color buffer.
 + */
 +static void
 +copy_back_to_front(struct st_context *st,
 +                   struct gl_framebuffer *fb,
 +                   gl_buffer_index frontIndex,
 +                   gl_buffer_index backIndex)
 +
 +{
 +   struct st_framebuffer *stfb = (struct st_framebuffer *) fb;
 +   struct pipe_surface *surf_front, *surf_back;
 +
 +   (void) st_get_framebuffer_surface(stfb, frontIndex, &surf_front);
 +   (void) st_get_framebuffer_surface(stfb, backIndex, &surf_back);
 +
 +   if (surf_front && surf_back) {
 +      st->pipe->surface_copy(st->pipe,
 +                             surf_front, 0, 0,  /* dest */
 +                             surf_back, 0, 0,   /* src */
 +                             fb->Width, fb->Height);
 +   }
 +}
 +
 +
 +/**
 + * Check if we're drawing into, or read from, a front color buffer.  If the
 + * front buffer is missing, create it now.
 + *
 + * The back color buffer must exist since we'll use its format/samples info
 + * for creating the front buffer.
 + *
 + * \param frontIndex  either BUFFER_FRONT_LEFT or BUFFER_FRONT_RIGHT
 + * \param backIndex  either BUFFER_BACK_LEFT or BUFFER_BACK_RIGHT
 + */
 +static void
 +check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb,
 +                          gl_buffer_index frontIndex,
 +                          gl_buffer_index backIndex)
 +{
 +   if (fb->Attachment[frontIndex].Renderbuffer == NULL) {
 +      GLboolean create = GL_FALSE;
 +
 +      /* check if drawing to or reading from front buffer */
 +      if (fb->_ColorReadBufferIndex == frontIndex) {
 +         create = GL_TRUE;
 +      }
 +      else {
 +         GLuint b;
 +         for (b = 0; b < fb->_NumColorDrawBuffers; b++) {
 +            if (fb->_ColorDrawBufferIndexes[b] == frontIndex) {
 +               create = GL_TRUE;
 +               break;
 +            }
 +         }
 +      }
 +
 +      if (create) {
 +         struct st_renderbuffer *back;
 +         struct gl_renderbuffer *front;
 +         enum pipe_format colorFormat;
 +         uint samples;
 +
 +         if (0)
 +            _mesa_debug(ctx, "Allocate new front buffer\n");
 +
 +         /* get back renderbuffer info */
 +         back = st_renderbuffer(fb->Attachment[backIndex].Renderbuffer);
 +         colorFormat = back->format;
 +         samples = back->Base.NumSamples;
 +
 +         /* create front renderbuffer */
++         front = st_new_renderbuffer_fb(colorFormat, samples, FALSE);
 +         _mesa_add_renderbuffer(fb, frontIndex, front);
 +
 +         /* alloc texture/surface for new front buffer */
 +         front->AllocStorage(ctx, front, front->InternalFormat,
 +                             fb->Width, fb->Height);
 +
 +         /* initialize the front color buffer contents by copying
 +          * the back buffer.
 +          */
 +         copy_back_to_front(ctx->st, fb, frontIndex, backIndex);
 +      }
 +   }
 +}
 +
 +
 +/**
 + * If front left/right color buffers are missing, create them now.
 + */
 +static void
 +check_create_front_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
 +{
 +   /* check if we need to create the front left buffer now */
 +   check_create_front_buffer(ctx, fb, BUFFER_FRONT_LEFT, BUFFER_BACK_LEFT);
 +
 +   if (fb->Visual.stereoMode) {
 +      check_create_front_buffer(ctx, fb, BUFFER_FRONT_RIGHT, BUFFER_BACK_RIGHT);
 +   }
 +
 +   st_invalidate_state(ctx, _NEW_BUFFERS);
 +}
 +
 +
 +/**
 + * Called via glDrawBuffer.
 + */
 +static void
 +st_DrawBuffers(GLcontext *ctx, GLsizei count, const GLenum *buffers)
 +{
 +   (void) count;
 +   (void) buffers;
 +   check_create_front_buffers(ctx, ctx->DrawBuffer);
 +}
 +
 +
 +/**
 + * Called via glReadBuffer.
 + */
 +static void
 +st_ReadBuffer(GLcontext *ctx, GLenum buffer)
 +{
 +   (void) buffer;
 +   check_create_front_buffers(ctx, ctx->ReadBuffer);
 +}
 +
 +
  void st_init_fbo_functions(struct dd_function_table *functions)
  {
     functions->NewFramebuffer = st_new_framebuffer;
index fd77d0a95b04c76b1e643b4a8142e3ef7ec96a74,9a199550d9f45098879cfa93bfb4caab35988250..bea6eb89c3ecf0b7782df89757c37bc7efd7af6a
@@@ -44,8 -40,14 +40,15 @@@ struct st_renderbuffe
     struct pipe_texture *texture;
     struct pipe_surface *surface; /* temporary view into texture */
     enum pipe_format format;  /** preferred format, or PIPE_FORMAT_NONE */
 +   GLboolean defined;        /**< defined contents? */
  
+    /**
+     * Used only when hardware accumulation buffers are not supported.
+     */
+    boolean software;
+    size_t stride;
+    void *data;
+    
     struct st_texture_object *rtt;  /**< GL render to texture's texture */
     int rtt_level, rtt_face, rtt_slice;
  
index ef800291ccdd2dd0865d4e29ad926764b1ba9363,331575660d300ad148d599327dd709aabfd1c0bd..7072cbe62c7f598604d1e75f75819b2e92738aed
@@@ -58,19 -58,19 +58,19 @@@ st_create_framebuffer( const __GLcontex
  
        _mesa_initialize_framebuffer(&stfb->Base, visual);
  
 -      {
 -         /* fake frontbuffer */
 -         /* XXX allocation should only happen in the unusual case
 -            it's actually needed */
 +      if (visual->doubleBufferMode) {
           struct gl_renderbuffer *rb
-             = st_new_renderbuffer_fb(colorFormat, samples);
+             = st_new_renderbuffer_fb(colorFormat, samples, FALSE);
 -         _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb);
 +         _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb);
        }
 -
 -      if (visual->doubleBufferMode) {
 +      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().
 +          */
           struct gl_renderbuffer *rb
-             = st_new_renderbuffer_fb(colorFormat, samples);
+             = st_new_renderbuffer_fb(colorFormat, samples, FALSE);
 -         _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb);
 +         _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb);
        }
  
        if (depthFormat == stencilFormat && depthFormat != PIPE_FORMAT_NONE) {