Merge branch 'mesa_7_5_branch'
[mesa.git] / src / gallium / winsys / xlib / xlib_softpipe.c
index e8513069fed3b7cf41b55b70cf6f5048a9b22558..44b8464518ab7176d4892fcf1ae2eacaf32cbfa4 100644 (file)
 #undef ASSERT
 #undef Elements
 
-#include "pipe/p_winsys.h"
+#include "pipe/internal/p_winsys_screen.h"
 #include "pipe/p_format.h"
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "softpipe/sp_winsys.h"
+#include "softpipe/sp_texture.h"
 
 #include "xlib.h"
 
@@ -58,10 +59,12 @@ struct xm_buffer
    boolean userBuffer;  /** Is this a user-space buffer? */
    void *data;
    void *mapped;
-   
+
    XImage *tempImage;
+#ifdef USE_XSHM
    int shm;
    XShmSegmentInfo shminfo;
+#endif
 };
 
 
@@ -72,7 +75,9 @@ struct xmesa_pipe_winsys
 {
    struct pipe_winsys base;
 /*   struct xmesa_visual *xm_visual; */
+#ifdef USE_XSHM
    int shm;
+#endif
 };
 
 
@@ -88,7 +93,13 @@ xm_buffer( struct pipe_buffer *buf )
 /**
  * X Shared Memory Image extension code
  */
+#ifdef USE_XSHM
 #define XSHM_ENABLED(b) ((b)->shm)
+#else
+#define XSHM_ENABLED(b) 0
+#endif
+
+#ifdef USE_XSHM
 
 static volatile int mesaXErrorFlag = 0;
 
@@ -169,8 +180,12 @@ alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb,
       (void) XSetErrorHandler(old_handler);
       return;
    }
+
+   b->shm = 1;
 }
 
+#endif /* USE_XSHM */
+
 
 
 /* Most callbacks map direcly onto dri_bufmgr operations:
@@ -192,12 +207,12 @@ xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
 }
 
 static void
-xm_buffer_destroy(struct pipe_winsys *pws,
-                  struct pipe_buffer *buf)
+xm_buffer_destroy(struct pipe_buffer *buf)
 {
    struct xm_buffer *oldBuf = xm_buffer(buf);
 
    if (oldBuf->data) {
+#ifdef USE_XSHM
       if (oldBuf->shminfo.shmid >= 0) {
          shmdt(oldBuf->shminfo.shmaddr);
          shmctl(oldBuf->shminfo.shmid, IPC_RMID, 0);
@@ -206,6 +221,7 @@ xm_buffer_destroy(struct pipe_winsys *pws,
          oldBuf->shminfo.shmaddr = (char *) -1;
       }
       else
+#endif
       {
          if (!oldBuf->userBuffer) {
             align_free(oldBuf->data);
@@ -219,17 +235,17 @@ xm_buffer_destroy(struct pipe_winsys *pws,
 }
 
 
-
 /**
  * Display/copy the image in the surface into the X window specified
  * by the XMesaBuffer.
  */
 static void
-xlib_softpipe_display_surface(struct xmesa_buffer *b, 
+xlib_softpipe_display_surface(struct xmesa_buffer *b,
                               struct pipe_surface *surf)
 {
    XImage *ximage;
-   struct xm_buffer *xm_buf = xm_buffer(surf->buffer);
+   struct softpipe_texture *spt = softpipe_texture(surf->texture);
+   struct xm_buffer *xm_buf = xm_buffer(spt->buffer);
    static boolean no_swap = 0;
    static boolean firsttime = 1;
 
@@ -241,20 +257,26 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b,
    if (no_swap)
       return;
 
+#ifdef USE_XSHM
    if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) {
-      assert(surf->block.width == 1);
-      assert(surf->block.height == 1);
-      alloc_shm_ximage(xm_buf, b, surf->stride/surf->block.size, surf->height);
+      assert(surf->texture->block.width == 1);
+      assert(surf->texture->block.height == 1);
+      alloc_shm_ximage(xm_buf, b, spt->stride[surf->level] /
+                       surf->texture->block.size, surf->height);
    }
+#endif
 
    ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage;
    ximage->data = xm_buf->data;
 
    /* display image in Window */
+#ifdef USE_XSHM
    if (XSHM_ENABLED(xm_buf)) {
       XShmPutImage(b->xm_visual->display, b->drawable, b->gc,
                    ximage, 0, 0, 0, 0, surf->width, surf->height, False);
-   } else {
+   } else
+#endif
+   {
       /* check that the XImage has been previously initialized */
       assert(ximage->format);
       assert(ximage->bitmap_unit);
@@ -262,7 +284,7 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b,
       /* update XImage's fields */
       ximage->width = surf->width;
       ximage->height = surf->height;
-      ximage->bytes_per_line = surf->stride;
+      ximage->bytes_per_line = spt->stride[surf->level];
 
       XPutImage(b->xm_visual->display, b->drawable, b->gc,
                 ximage, 0, 0, 0, 0, surf->width, surf->height);
@@ -299,12 +321,9 @@ xm_buffer_create(struct pipe_winsys *pws,
                  unsigned size)
 {
    struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
+#ifdef USE_XSHM
    struct xmesa_pipe_winsys *xpws = (struct xmesa_pipe_winsys *) pws;
 
-   buffer->base.refcount = 1;
-   buffer->base.alignment = alignment;
-   buffer->base.usage = usage;
-   buffer->base.size = size;
    buffer->shminfo.shmid = -1;
    buffer->shminfo.shmaddr = (char *) -1;
 
@@ -313,12 +332,17 @@ xm_buffer_create(struct pipe_winsys *pws,
 
       if (alloc_shm(buffer, size)) {
          buffer->data = buffer->shminfo.shmaddr;
+         buffer->shm = 1;
       }
    }
+#endif
 
-   if (buffer->data == NULL) {
-      buffer->shm = 0;
+   pipe_reference_init(&buffer->base.reference, 1);
+   buffer->base.alignment = alignment;
+   buffer->base.usage = usage;
+   buffer->base.size = size;
 
+   if (buffer->data == NULL) {
       /* align to 16-byte multiple for Cell */
       buffer->data = align_malloc(size, max(alignment, 16));
    }
@@ -334,87 +358,37 @@ static struct pipe_buffer *
 xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
 {
    struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-   buffer->base.refcount = 1;
+   pipe_reference_init(&buffer->base.reference, 1);
    buffer->base.size = bytes;
    buffer->userBuffer = TRUE;
    buffer->data = ptr;
+#ifdef USE_XSHM
    buffer->shm = 0;
+#endif
 
    return &buffer->base;
 }
 
 
-
-/**
- * Round n up to next multiple.
- */
-static INLINE unsigned
-round_up(unsigned n, unsigned multiple)
-{
-   return (n + multiple - 1) & ~(multiple - 1);
-}
-
-static int
-xm_surface_alloc_storage(struct pipe_winsys *winsys,
-                         struct pipe_surface *surf,
+static struct pipe_buffer *
+xm_surface_buffer_create(struct pipe_winsys *winsys,
                          unsigned width, unsigned height,
-                         enum pipe_format format, 
-                         unsigned flags,
-                         unsigned tex_usage)
+                         enum pipe_format format,
+                         unsigned usage,
+                         unsigned *stride)
 {
    const unsigned alignment = 64;
+   struct pipe_format_block block;
+   unsigned nblocksx, nblocksy;
 
-   surf->width = width;
-   surf->height = height;
-   surf->format = format;
-   pf_get_block(format, &surf->block);
-   surf->nblocksx = pf_get_nblocksx(&surf->block, width);
-   surf->nblocksy = pf_get_nblocksy(&surf->block, height);
-   surf->stride = round_up(surf->nblocksx * surf->block.size, alignment);
-   surf->usage = flags;
-
-   assert(!surf->buffer);
-   surf->buffer = winsys->buffer_create(winsys, alignment,
-                                        PIPE_BUFFER_USAGE_PIXEL,
-                                        surf->stride * surf->nblocksy);
-
-   if(!surf->buffer)
-      return -1;
-   
-   return 0;
-}
-
-
-/**
- * Called via winsys->surface_alloc() to create new surfaces.
- */
-static struct pipe_surface *
-xm_surface_alloc(struct pipe_winsys *ws)
-{
-   struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface);
+   pf_get_block(format, &block);
+   nblocksx = pf_get_nblocksx(&block, width);
+   nblocksy = pf_get_nblocksy(&block, height);
+   *stride = align(nblocksx * block.size, alignment);
 
-   assert(ws);
-
-   surface->refcount = 1;
-   surface->winsys = ws;
-
-   return surface;
-}
-
-
-
-static void
-xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
-{
-   struct pipe_surface *surf = *s;
-   assert(!surf->texture);
-   surf->refcount--;
-   if (surf->refcount == 0) {
-      if (surf->buffer)
-       winsys_buffer_reference(winsys, &surf->buffer, NULL);
-      free(surf);
-   }
-   *s = NULL;
+   return winsys->buffer_create(winsys, alignment,
+                                usage,
+                                *stride * nblocksy);
 }
 
 
@@ -464,9 +438,7 @@ xlib_create_softpipe_winsys( void )
       ws->base.buffer_unmap = xm_buffer_unmap;
       ws->base.buffer_destroy = xm_buffer_destroy;
 
-      ws->base.surface_alloc = xm_surface_alloc;
-      ws->base.surface_alloc_storage = xm_surface_alloc_storage;
-      ws->base.surface_release = xm_surface_release;
+      ws->base.surface_buffer_create = xm_surface_buffer_create;
 
       ws->base.fence_reference = xm_fence_reference;
       ws->base.fence_signalled = xm_fence_signalled;
@@ -510,7 +482,7 @@ xlib_create_softpipe_context( struct pipe_screen *screen,
 {
    struct pipe_context *pipe;
    
-   pipe = softpipe_create(screen, screen->winsys, NULL);
+   pipe = softpipe_create(screen);
    if (pipe == NULL)
       goto fail;