gallium: remove usage of winsys->surface_alloc_storage from state tracker
authorKeith Whitwell <keith@tungstengraphics.com>
Fri, 2 May 2008 13:27:10 +0000 (14:27 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Fri, 2 May 2008 13:27:10 +0000 (14:27 +0100)
Allocate a texture containing storage instead.

Also clean up ACCUM buffer allocation slightly -- drivers will need
some changes to texture allocation logic to accomodate the concept of
a texture that will only as image storage by the CPU, but it's cleaner
than it was.

src/gallium/include/pipe/p_state.h
src/mesa/state_tracker/st_cb_fbo.c

index 47e57e2957cd39375ba2b8e191761b1e9b993fca..277ee4b31905dabbd60134f6ce030e0a768d944b 100644 (file)
@@ -299,6 +299,8 @@ struct pipe_texture
    unsigned cpp:8;
    unsigned last_level:8;    /**< Index of last mipmap level present/defined */
    unsigned compressed:1;
+   
+   unsigned usage;
 
    /* These are also refcounted:
     */
index 7fdc0bddd6732e32cbbc50a53737b5cae57c03da..b1747141710b15ef1ef2a5286d36a900b0a5ef30 100644 (file)
@@ -90,90 +90,79 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
 {
    struct pipe_context *pipe = ctx->st->pipe;
    struct st_renderbuffer *strb = st_renderbuffer(rb);
-   enum pipe_format pipeFormat;
-   unsigned flags = (PIPE_BUFFER_USAGE_CPU_WRITE | 
-                     PIPE_BUFFER_USAGE_CPU_READ |
-                     PIPE_BUFFER_USAGE_GPU_WRITE |
-                     PIPE_BUFFER_USAGE_GPU_READ);
-   int ret;
 
+   struct pipe_texture template, *texture;
+
+   /* Free the old surface (and texture if we hold the last
+    * reference):
+    */
    pipe_surface_reference( &strb->surface, NULL );
 
-   if (!strb->surface) {
-      /* first time surface creation */
-      strb->surface = pipe->winsys->surface_alloc(pipe->winsys);
-      assert(strb->surface);
-      assert(strb->surface->refcount);
-      assert(strb->surface->winsys);
-      if (!strb->surface)
-         return GL_FALSE;
-   }
-#if 0
-   else if (strb->surface->buffer) {
-      /* release/discard the old surface buffer */
-      pipe_reference_buffer(pipe, &strb->surface->buffer, NULL);
-   }
-#else
-   else {
-      assert(0);
-   }
-#endif
-   /* Determine surface format here */
+   memset(&template, 0, sizeof(template));
+
    if (strb->format != PIPE_FORMAT_NONE) {
-      assert(strb->format != 0);
-      /* we'll hit this for front/back color bufs */
-      pipeFormat = strb->format;
+      template.format = strb->format;
    }
    else {
-      pipeFormat = st_choose_renderbuffer_format(pipe, internalFormat);
+      template.format = st_choose_renderbuffer_format(pipe, internalFormat);
    }
 
-   init_renderbuffer_bits(strb, pipeFormat);
-
-   ret = pipe->winsys->surface_alloc_storage(pipe->winsys,
-                                             strb->surface,
-                                             width,
-                                             height,
-                                             pipeFormat,
-                                             flags);
-   if (ret || !strb->surface->buffer) {
-      if (pipeFormat == DEFAULT_ACCUM_PIPE_FORMAT) {
-         /* Accum buffer.  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.
-          */
-         int sz, mult;
-         enum pipe_format accum_format;
-
-         /* allocate a buffer of (typically) double height to get 64bpp */
-         accum_format = st_choose_renderbuffer_format(pipe, GL_RGBA);
-         sz = pf_get_size(accum_format);
-         mult = pf_get_size(DEFAULT_ACCUM_PIPE_FORMAT) / sz;
-
-         ret = pipe->winsys->surface_alloc_storage(pipe->winsys,
-                                                   strb->surface,
-                                                   width, height * mult,
-                                                   accum_format, flags);
-         if (ret)
-            return GL_FALSE; /* we've _really_ failed */
-
-      }
-      else {
-         return GL_FALSE; /* out of memory, try s/w buffer? */
-      }
+   strb->Base.Width  = width;
+   strb->Base.Height = height;
+   init_renderbuffer_bits(strb, template.format);
+
+   template.compressed = 0;
+   template.cpp = pf_get_size(template.format);
+   template.width[0] = width;
+   template.height[0] = height;
+   template.depth[0] = 1;
+   template.last_level = 0;
+   template.usage = (PIPE_BUFFER_USAGE_CPU_WRITE | 
+                     PIPE_BUFFER_USAGE_CPU_READ |
+                     PIPE_BUFFER_USAGE_GPU_WRITE |
+                     PIPE_BUFFER_USAGE_GPU_READ);
+
+   texture = pipe->screen->texture_create( pipe->screen,
+                                           &template );
+
+   /* 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 (!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.
+       */
+      template.usage = (PIPE_BUFFER_USAGE_CPU_READ |
+                        PIPE_BUFFER_USAGE_CPU_WRITE);
+
+      texture = pipe->screen->texture_create( pipe->screen,
+                                              &template );
    }
 
-   ASSERT(strb->surface->buffer);
-   ASSERT(strb->surface->format);
-   ASSERT(strb->surface->cpp);
-   ASSERT(strb->surface->width == width);
-   /*ASSERT(strb->surface->height == height);*/
-   ASSERT(strb->surface->pitch);
+   if (!texture) 
+      return FALSE;
 
-   strb->Base.Width  = width;
-   strb->Base.Height = height;
+   strb->surface = pipe->screen->get_tex_surface( pipe->screen,
+                                                  texture,
+                                                  0, 0, 0,
+                                                  template.usage );
+
+   pipe_texture_reference( &texture, NULL );
 
-   return GL_TRUE;
+   assert(strb->surface->buffer);
+   assert(strb->surface->format);
+   assert(strb->surface->cpp);
+   assert(strb->surface->width == width);
+   assert(strb->surface->height == height);
+   assert(strb->surface->pitch);
+
+
+   return strb->surface != NULL;
 }
 
 
@@ -185,10 +174,7 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb)
 {
    struct st_renderbuffer *strb = st_renderbuffer(rb);
    ASSERT(strb);
-   if (strb->surface) {
-      struct pipe_winsys *ws = strb->surface->winsys;
-      ws->surface_release(ws, &strb->surface);
-   }
+   pipe_surface_reference(&strb->surface, NULL);
    free(strb);
 }