Mesa (mesa_7_5_branch): mesa: Pure software accum buffer.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Wed Jun 10 14:42:19 UTC 2009


Module: Mesa
Branch: mesa_7_5_branch
Commit: 52411a1951da10bebc439a30c02c7ca99bc27c9c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=52411a1951da10bebc439a30c02c7ca99bc27c9c

Author: José Fonseca <jfonseca at vmware.com>
Date:   Wed Jun 10 15:39:02 2009 +0100

mesa: Pure software accum buffer.

The existing implementation was already implemented on software, but relied
on the pipe driver to always support the R16G16B16A16_SNORM format. This
patch eliminates that, without prejudice against a future hardware-only
implementation.

It also avoids some of the short <-> float conversions, and only does a read
transfer of the color buffer on GL_RETURN if absolutely necessary.

---

 src/mesa/state_tracker/st_cb_accum.c    |  244 ++++++++++++-------------------
 src/mesa/state_tracker/st_cb_fbo.c      |  147 ++++++++++---------
 src/mesa/state_tracker/st_cb_fbo.h      |   13 +-
 src/mesa/state_tracker/st_framebuffer.c |   17 +-
 4 files changed, 187 insertions(+), 234 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c
index 7f793cf..9518157 100644
--- a/src/mesa/state_tracker/st_cb_accum.c
+++ b/src/mesa/state_tracker/st_cb_accum.c
@@ -48,10 +48,6 @@
 #include "util/u_tile.h"
 
 
-#define UNCLAMPED_FLOAT_TO_SHORT(us, f)  \
-   us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
-
-
 /**
  * For hardware that supports deep color buffers, we could accelerate
  * most/all the accum operations with blending/texturing.
@@ -59,74 +55,20 @@
  */
 
 
-/**
- * Wrapper for pipe_get_tile_rgba().  Do format/cpp override to make the
- * tile util function think the surface is 16bit/channel, even if it's not.
- * See also: st_renderbuffer_alloc_storage()
- */
-static void
-acc_get_tile_rgba(struct pipe_context *pipe, struct pipe_transfer *acc_pt,
-                  uint x, uint y, uint w, uint h, float *p)
-{
-   const enum pipe_format f = acc_pt->format;
-   const struct pipe_format_block b = acc_pt->block;
-
-   acc_pt->format = DEFAULT_ACCUM_PIPE_FORMAT;
-   acc_pt->block.size = 8;
-   acc_pt->block.width = 1;
-   acc_pt->block.height = 1;
-
-   pipe_get_tile_rgba(acc_pt, x, y, w, h, p);
-
-   acc_pt->format = f;
-   acc_pt->block = b;
-}
-
-
-/**
- * Wrapper for pipe_put_tile_rgba().  Do format/cpp override to make the
- * tile util function think the surface is 16bit/channel, even if it's not.
- * See also: st_renderbuffer_alloc_storage()
- */
-static void
-acc_put_tile_rgba(struct pipe_context *pipe, struct pipe_transfer *acc_pt,
-                  uint x, uint y, uint w, uint h, const float *p)
-{
-   enum pipe_format f = acc_pt->format;
-   const struct pipe_format_block b = acc_pt->block;
-
-   acc_pt->format = DEFAULT_ACCUM_PIPE_FORMAT;
-   acc_pt->block.size = 8;
-   acc_pt->block.width = 1;
-   acc_pt->block.height = 1;
-
-   pipe_put_tile_rgba(acc_pt, x, y, w, h, p);
-
-   acc_pt->format = f;
-   acc_pt->block = b;
-}
-
-
-
 void
 st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
 {
    struct st_renderbuffer *acc_strb = st_renderbuffer(rb);
-   struct pipe_transfer *acc_pt;
-   struct pipe_screen *screen = ctx->st->pipe->screen;
    const GLint xpos = ctx->DrawBuffer->_Xmin;
    const GLint ypos = ctx->DrawBuffer->_Ymin;
    const GLint width = ctx->DrawBuffer->_Xmax - xpos;
    const GLint height = ctx->DrawBuffer->_Ymax - ypos;
-   GLubyte *map;
-
-   acc_pt = st_cond_flush_get_tex_transfer(st_context(ctx), acc_strb->texture,
-					   0, 0, 0,
-					   PIPE_TRANSFER_WRITE, xpos, ypos,
-					   width, height);
-   map = screen->transfer_map(screen, acc_pt);
+   size_t stride = acc_strb->stride;
+   GLubyte *data = acc_strb->data;
 
-   /* note acc_strb->format might not equal acc_pt->format */
+   if(!data)
+      return;
+   
    switch (acc_strb->format) {
    case PIPE_FORMAT_R16G16B16A16_SNORM:
       {
@@ -136,7 +78,7 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
          GLshort a = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]);
          int i, j;
          for (i = 0; i < height; i++) {
-            GLshort *dst = (GLshort *) (map + i * acc_pt->stride + xpos * 8);
+            GLshort *dst = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
             for (j = 0; j < width; j++) {
                dst[0] = r;
                dst[1] = g;
@@ -150,9 +92,6 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
    default:
       _mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()");
    }
-
-   screen->transfer_unmap(screen, acc_pt);
-   screen->tex_transfer_destroy(acc_pt);
 }
 
 
@@ -162,27 +101,18 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
           GLint xpos, GLint ypos, GLint width, GLint height,
           struct st_renderbuffer *acc_strb)
 {
-   struct pipe_screen *screen = ctx->st->pipe->screen;
-   struct pipe_transfer *acc_pt;
-   GLubyte *map;
-
-   acc_pt = st_cond_flush_get_tex_transfer(st_context(ctx), acc_strb->texture,
-					   0, 0, 0,
-					   PIPE_TRANSFER_READ_WRITE,
-					   xpos, ypos,
-					   width, height);
-   map = screen->transfer_map(screen, acc_pt);
-
-   /* note acc_strb->format might not equal acc_pt->format */
+   size_t stride = acc_strb->stride;
+   GLubyte *data = acc_strb->data;
+
    switch (acc_strb->format) {
    case PIPE_FORMAT_R16G16B16A16_SNORM:
       {
          int i, j;
          for (i = 0; i < height; i++) {
-            GLshort *acc = (GLshort *) (map + (ypos + i) * acc_pt->stride + xpos * 8);
+            GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
             for (j = 0; j < width * 4; j++) {
-               float val = SHORT_TO_FLOAT(acc[j]) * scale + bias;
-               acc[j] = FLOAT_TO_SHORT(val);
+               float val = SHORT_TO_FLOAT(*acc) * scale + bias;
+               *acc++ = FLOAT_TO_SHORT(val);
             }
          }
       }
@@ -190,9 +120,6 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
    default:
       _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
    }
-
-   screen->transfer_unmap(screen, acc_pt);
-   screen->tex_transfer_destroy(acc_pt);
 }
 
 
@@ -204,39 +131,39 @@ accum_accum(struct st_context *st, GLfloat value,
 {
    struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = pipe->screen;
-   struct pipe_transfer *acc_trans, *color_trans;
-   GLfloat *colorBuf, *accBuf;
-   GLint i;
-
-   acc_trans = st_cond_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0,
-					      PIPE_TRANSFER_READ, xpos, ypos,
-					      width, height);
+   struct pipe_transfer *color_trans;
+   size_t stride = acc_strb->stride;
+   GLubyte *data = acc_strb->data;
+   GLfloat *buf;
 
    color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture,
 						0, 0, 0,
 						PIPE_TRANSFER_READ, xpos, ypos,
 						width, height);
 
-   colorBuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
-   accBuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
+   buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
 
-   pipe_get_tile_rgba(color_trans, 0, 0, width, height, colorBuf);
-   acc_get_tile_rgba(pipe, acc_trans, 0, 0, width, height, accBuf);
+   pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf);
 
-   for (i = 0; i < 4 * width * height; i++) {
-      accBuf[i] = accBuf[i] + colorBuf[i] * value;
+   switch (acc_strb->format) {
+   case PIPE_FORMAT_R16G16B16A16_SNORM:
+      {
+         const GLfloat *color = buf;
+         int i, j;
+         for (i = 0; i < height; i++) {
+            GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
+            for (j = 0; j < width * 4; j++) {
+               float val = *color++ * value;
+               *acc++ += FLOAT_TO_SHORT(val);
+            }
+         }
+      }
+      break;
+   default:
+      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
    }
 
-   screen->tex_transfer_destroy(acc_trans);
-   acc_trans = st_no_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0,
-					    PIPE_TRANSFER_WRITE, xpos, ypos,
-					    width, height);
-
-   acc_put_tile_rgba(pipe, acc_trans, 0, 0, width, height, accBuf);
-
-   _mesa_free(colorBuf);
-   _mesa_free(accBuf);
-   screen->tex_transfer_destroy(acc_trans);
+   _mesa_free(buf);
    screen->tex_transfer_destroy(color_trans);
 }
 
@@ -249,13 +176,10 @@ accum_load(struct st_context *st, GLfloat value,
 {
    struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = pipe->screen;
-   struct pipe_transfer *acc_trans, *color_trans;
+   struct pipe_transfer *color_trans;
+   size_t stride = acc_strb->stride;
+   GLubyte *data = acc_strb->data;
    GLfloat *buf;
-   GLint i;
-
-   acc_trans = st_cond_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0,
-					      PIPE_TRANSFER_WRITE, xpos, ypos,
-					      width, height);
 
    color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture,
 						0, 0, 0,
@@ -266,14 +190,25 @@ accum_load(struct st_context *st, GLfloat value,
 
    pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf);
 
-   for (i = 0; i < 4 * width * height; i++) {
-      buf[i] = buf[i] * value;
+   switch (acc_strb->format) {
+   case PIPE_FORMAT_R16G16B16A16_SNORM:
+      {
+         const GLfloat *color = buf;
+         int i, j;
+         for (i = 0; i < height; i++) {
+            GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
+            for (j = 0; j < width * 4; j++) {
+               float val = *color++ * value;
+               *acc++ = FLOAT_TO_SHORT(val);
+            }
+         }
+      }
+      break;
+   default:
+      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
    }
 
-   acc_put_tile_rgba(pipe, acc_trans, 0, 0, width, height, buf);
-
    _mesa_free(buf);
-   screen->tex_transfer_destroy(acc_trans);
    screen->tex_transfer_destroy(color_trans);
 }
 
@@ -287,48 +222,58 @@ accum_return(GLcontext *ctx, GLfloat value,
    struct pipe_context *pipe = ctx->st->pipe;
    struct pipe_screen *screen = pipe->screen;
    const GLubyte *colormask = ctx->Color.ColorMask;
-   struct pipe_transfer *acc_trans, *color_trans;
-   GLfloat *abuf, *cbuf = NULL;
-   GLint i, ch;
-
-   abuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
+   enum pipe_transfer_usage usage;
+   struct pipe_transfer *color_trans;
+   size_t stride = acc_strb->stride;
+   const GLubyte *data = acc_strb->data;
+   GLfloat *buf;
 
-   acc_trans = st_cond_flush_get_tex_transfer(st_context(ctx),
-					      acc_strb->texture, 0, 0, 0,
-					      PIPE_TRANSFER_READ, xpos, ypos,
-					      width, height);
+   buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
 
+   if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3])
+      usage = PIPE_TRANSFER_READ_WRITE;
+   else
+      usage = PIPE_TRANSFER_WRITE;
+   
    color_trans = st_cond_flush_get_tex_transfer(st_context(ctx),
 						color_strb->texture, 0, 0, 0,
-						PIPE_TRANSFER_READ_WRITE,
+						usage,
 						xpos, ypos,
 						width, height);
 
-   acc_get_tile_rgba(pipe, acc_trans, 0, 0, width, height, abuf);
-
-   if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) {
-      cbuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
-      pipe_get_tile_rgba(color_trans, 0, 0, width, height, cbuf);
-   }
+   if (usage != PIPE_TRANSFER_WRITE)
+      pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf);
 
-   for (i = 0; i < width * height; i++) {
-      for (ch = 0; ch < 4; ch++) {
-         if (colormask[ch]) {
-            GLfloat val = abuf[i * 4 + ch] * value;
-            abuf[i * 4 + ch] = CLAMP(val, 0.0f, 1.0f);
-         }
-         else {
-            abuf[i * 4 + ch] = cbuf[i * 4 + ch];
+   switch (acc_strb->format) {
+   case PIPE_FORMAT_R16G16B16A16_SNORM:
+      {
+         GLfloat *color = buf;
+         int i, j, ch;
+         for (i = 0; i < height; i++) {
+            const GLshort *acc = (const GLshort *) (data + (ypos + i) * stride + xpos * 8);
+            for (j = 0; j < width; j++) {
+               for (ch = 0; ch < 4; ch++) {
+                  if (colormask[ch]) {
+                     GLfloat val = SHORT_TO_FLOAT(*acc * value);
+                     *color = CLAMP(val, 0.0f, 1.0f);
+                  }
+                  else {
+                     /* No change */
+                  }
+                  ++acc;
+                  ++color;
+               }
+            }
          }
       }
+      break;
+   default:
+      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
    }
 
-   pipe_put_tile_rgba(color_trans, 0, 0, width, height, abuf);
+   pipe_put_tile_rgba(color_trans, 0, 0, width, height, buf);
 
-   _mesa_free(abuf);
-   if (cbuf)
-      _mesa_free(cbuf);
-   screen->tex_transfer_destroy(acc_trans);
+   _mesa_free(buf);
    screen->tex_transfer_destroy(color_trans);
 }
 
@@ -347,6 +292,9 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
    const GLint width = ctx->DrawBuffer->_Xmax - xpos;
    const GLint height = ctx->DrawBuffer->_Ymax - ypos;
 
+   if(!acc_strb->data)
+      return;
+   
    /* make sure color bufs aren't cached */
    st_flush( st, PIPE_FLUSH_RENDER_CACHE, NULL );
 
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index e003b6d..21ddf2f 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -88,91 +88,90 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
 {
    struct pipe_context *pipe = ctx->st->pipe;
    struct st_renderbuffer *strb = st_renderbuffer(rb);
-   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 );
-
-   /* Setup new texture template.
-    */
-   memset(&template, 0, sizeof(template));
-   template.target = PIPE_TEXTURE_2D;
-   if (strb->format != PIPE_FORMAT_NONE) {
-      template.format = strb->format;
-   }
-   else {
-      template.format = st_choose_renderbuffer_format(pipe, internalFormat);
-   }
-   pf_get_block(template.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(template.format)) {
-      template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
-   }
-   else {
-      template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
-                            PIPE_TEXTURE_USAGE_RENDER_TARGET);
-   }
+   enum pipe_format format;
 
+   if (strb->format != PIPE_FORMAT_NONE)
+      format = strb->format;
+   else
+      format = st_choose_renderbuffer_format(pipe, internalFormat);
+      
    /* init renderbuffer fields */
    strb->Base.Width  = width;
    strb->Base.Height = height;
-   init_renderbuffer_bits(strb, template.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->texture = pipe->screen->texture_create( pipe->screen,
-                                                 &template );
+   init_renderbuffer_bits(strb, format);
+
+   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 );
 
-   /* 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.
+      /* 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);
+      }
+
+      /* 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 );
 
-   }
-
-   if (!strb->texture) 
-      return FALSE;
+      if (!strb->texture) 
+         return FALSE;
 
-   strb->surface = pipe->screen->get_tex_surface( pipe->screen,
-                                                  strb->texture,
-                                                  0, 0, 0,
-                                                  surface_usage );
+      strb->surface = pipe->screen->get_tex_surface( pipe->screen,
+                                                     strb->texture,
+                                                     0, 0, 0,
+                                                     surface_usage );
 
-   assert(strb->surface->texture);
-   assert(strb->surface->format);
-   assert(strb->surface->width == width);
-   assert(strb->surface->height == height);
+      assert(strb->surface->texture);
+      assert(strb->surface->format);
+      assert(strb->surface->width == width);
+      assert(strb->surface->height == height);
 
 
-   return strb->surface != NULL;
+      return strb->surface != NULL;
+   }
 }
 
 
@@ -186,6 +185,7 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb)
    ASSERT(strb);
    pipe_surface_reference(&strb->surface, NULL);
    pipe_texture_reference(&strb->texture, NULL);
+   _mesa_free(strb->data);
    _mesa_free(strb);
 }
 
@@ -242,7 +242,7 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name)
  * renderbuffer).  The window system code determines the format.
  */
 struct gl_renderbuffer *
-st_new_renderbuffer_fb(enum pipe_format format, int samples)
+st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw)
 {
    struct st_renderbuffer *strb;
 
@@ -256,7 +256,8 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples)
    strb->Base.ClassID = 0x4242; /* just a unique value */
    strb->Base.NumSamples = samples;
    strb->format = format;
-
+   strb->software = sw;
+   
    switch (format) {
    case PIPE_FORMAT_A8R8G8B8_UNORM:
    case PIPE_FORMAT_B8G8R8A8_UNORM:
@@ -287,7 +288,7 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples)
       strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT;
       strb->Base._BaseFormat = GL_STENCIL_INDEX;
       break;
-   case DEFAULT_ACCUM_PIPE_FORMAT: /*PIPE_FORMAT_R16G16B16A16_SNORM*/
+   case PIPE_FORMAT_R16G16B16A16_SNORM:
       strb->Base.InternalFormat = GL_RGBA16;
       strb->Base._BaseFormat = GL_RGBA;
       break;
diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h
index 44fa9fe..9a19955 100644
--- a/src/mesa/state_tracker/st_cb_fbo.h
+++ b/src/mesa/state_tracker/st_cb_fbo.h
@@ -30,10 +30,6 @@
 #define ST_CB_FBO_H
 
 
-#define DEFAULT_ACCUM_PIPE_FORMAT PIPE_FORMAT_R16G16B16A16_SNORM
-
-
-
 /**
  * Derived renderbuffer class.  Just need to add a pointer to the
  * pipe surface.
@@ -45,6 +41,13 @@ struct st_renderbuffer
    struct pipe_surface *surface; /* temporary view into texture */
    enum pipe_format format;  /** preferred format, or PIPE_FORMAT_NONE */
 
+   /**
+    * 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;
 
@@ -62,7 +65,7 @@ st_renderbuffer(struct gl_renderbuffer *rb)
 
 
 extern struct gl_renderbuffer *
-st_new_renderbuffer_fb(enum pipe_format format, int samples);
+st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw);
 
 extern void
 st_init_fbo_functions(struct dd_function_table *functions);
diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c
index daaad65..3315756 100644
--- a/src/mesa/state_tracker/st_framebuffer.c
+++ b/src/mesa/state_tracker/st_framebuffer.c
@@ -63,20 +63,20 @@ st_create_framebuffer( const __GLcontextModes *visual,
          /* XXX allocation should only happen in the unusual case
             it's actually needed */
          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);
       }
 
       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_BACK_LEFT, rb);
       }
 
       if (depthFormat == stencilFormat && depthFormat != PIPE_FORMAT_NONE) {
          /* combined depth/stencil buffer */
          struct gl_renderbuffer *depthStencilRb
-            = st_new_renderbuffer_fb(depthFormat, samples);
+            = st_new_renderbuffer_fb(depthFormat, samples, FALSE);
          /* note: bind RB to two attachment points */
          _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb);
          _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb);
@@ -87,34 +87,35 @@ st_create_framebuffer( const __GLcontextModes *visual,
          if (visual->depthBits == 32) {
             /* 32-bit depth buffer */
             struct gl_renderbuffer *depthRb
-               = st_new_renderbuffer_fb(depthFormat, samples);
+               = st_new_renderbuffer_fb(depthFormat, samples, FALSE);
             _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
          }
          else if (visual->depthBits == 24) {
             /* 24-bit depth buffer, ignore stencil bits */
             struct gl_renderbuffer *depthRb
-               = st_new_renderbuffer_fb(depthFormat, samples);
+               = st_new_renderbuffer_fb(depthFormat, samples, FALSE);
             _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
          }
          else if (visual->depthBits > 0) {
             /* 16-bit depth buffer */
             struct gl_renderbuffer *depthRb
-               = st_new_renderbuffer_fb(depthFormat, samples);
+               = st_new_renderbuffer_fb(depthFormat, samples, FALSE);
             _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
          }
 
          if (visual->stencilBits > 0) {
             /* 8-bit stencil */
             struct gl_renderbuffer *stencilRb
-               = st_new_renderbuffer_fb(stencilFormat, samples);
+               = st_new_renderbuffer_fb(stencilFormat, samples, FALSE);
             _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb);
          }
       }
 
       if (visual->accumRedBits > 0) {
          /* 16-bit/channel accum */
+         /* TODO: query the pipe screen for accumulation buffer format support */
          struct gl_renderbuffer *accumRb
-            = st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT, 0); /* XXX accum isn't multisampled right? */
+            = st_new_renderbuffer_fb(PIPE_FORMAT_R16G16B16A16_SNORM, 0, TRUE);
          _mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb);
       }
 




More information about the mesa-commit mailing list