Blame SOURCES/mesa-8.0-llvmpipe-shmget.patch

230118
diff -up mesa-20120424/src/gallium/state_trackers/dri/sw/drisw.c.jx mesa-20120424/src/gallium/state_trackers/dri/sw/drisw.c
230118
--- mesa-20120424/src/gallium/state_trackers/dri/sw/drisw.c.jx	2012-04-24 07:37:03.000000000 -0400
230118
+++ mesa-20120424/src/gallium/state_trackers/dri/sw/drisw.c	2012-05-16 13:30:36.596312047 -0400
230118
@@ -252,8 +252,6 @@ drisw_update_tex_buffer(struct dri_drawa
230118
    struct pipe_transfer *transfer;
230118
    char *map;
230118
    int x, y, w, h;
230118
-   int ximage_stride, line;
230118
-   int cpp = util_format_get_blocksize(res->format);
230118
 
230118
    get_drawable_info(dPriv, &x, &y, &w, &h);
230118
 
230118
@@ -266,14 +264,6 @@ drisw_update_tex_buffer(struct dri_drawa
230118
    /* Copy the Drawable content to the mapped texture buffer */
230118
    get_image(dPriv, x, y, w, h, map);
230118
 
230118
-   /* The pipe transfer has a pitch rounded up to the nearest 64 pixels. */
230118
-   ximage_stride = w * cpp;
230118
-   for (line = h-1; line; --line) {
230118
-      memmove(&map[line * transfer->stride],
230118
-              &map[line * ximage_stride],
230118
-              ximage_stride);
230118
-   }
230118
-
230118
    pipe_transfer_unmap(pipe, transfer);
230118
    pipe_transfer_destroy(pipe, transfer);
230118
 }
230118
diff -up mesa-20120424/src/glx/drisw_glx.c.jx mesa-20120424/src/glx/drisw_glx.c
230118
--- mesa-20120424/src/glx/drisw_glx.c.jx	2012-04-24 07:37:03.000000000 -0400
230118
+++ mesa-20120424/src/glx/drisw_glx.c	2012-05-16 13:29:25.087965268 -0400
230118
@@ -24,6 +24,9 @@
230118
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
230118
 
230118
 #include <X11/Xlib.h>
230118
+#include <sys/ipc.h>
230118
+#include <sys/shm.h>
230118
+#include <X11/extensions/XShm.h>
230118
 #include "glxclient.h"
230118
 #include <dlfcn.h>
230118
 #include "dri_common.h"
230118
@@ -206,6 +209,96 @@ swrastPutImage(__DRIdrawable * draw, int
230118
    ximage->data = NULL;
230118
 }
230118
 
230118
+static int shm_error;
230118
+
230118
+static int
230118
+shm_handler(Display *d, XErrorEvent *e)
230118
+{
230118
+    shm_error = 1;
230118
+    return 0;
230118
+}
230118
+
230118
+static int
230118
+align(int value, int alignment)
230118
+{
230118
+   return (value + alignment - 1) & ~(alignment - 1);
230118
+}
230118
+
230118
+/*
230118
+ * Slight fast path.  Short of changing how texture memory is allocated, we
230118
+ * have two options for getting the pixels out.  GetImage is clamped by the
230118
+ * server's write buffer size, so you end up doing lots of relatively small
230118
+ * requests (128k each or so), with two memcpys: down into the kernel, and
230118
+ * then back up.  ShmGetImage is one big blit into the shm segment (which
230118
+ * could be GPU DMA, in principle) and then another one here.
230118
+ */
230118
+static Bool
230118
+swrastShmGetImage(__DRIdrawable *read, char *data, struct drisw_drawable *prp)
230118
+{
230118
+    __GLXDRIdrawable *pread = &(prp->base);
230118
+    Display *dpy = pread->psc->dpy;
230118
+    XImage *ximage = prp->ximage;
230118
+    unsigned long image_size = ximage->height * ximage->bytes_per_line;
230118
+    Bool ret = 0;
230118
+    XShmSegmentInfo seg = { 0, -1, (void *)-1, 0 };
230118
+    int (*old_handler)(Display *, XErrorEvent *);
230118
+
230118
+    if (!XShmQueryExtension(dpy))
230118
+	goto out;
230118
+
230118
+    /* image setup */
230118
+    seg.shmid = shmget(IPC_PRIVATE, image_size, IPC_CREAT | 0777);
230118
+    if (seg.shmid < 0)
230118
+	goto out;
230118
+
230118
+    seg.shmaddr = shmat(seg.shmid, NULL, 0);
230118
+    if (seg.shmaddr == (void *)-1)
230118
+	goto out;
230118
+
230118
+    XSync(dpy, 0);
230118
+    old_handler = XSetErrorHandler(shm_handler);
230118
+    XShmAttach(dpy, &seg;;
230118
+    XSync(dpy, 0);
230118
+    XSetErrorHandler(old_handler);
230118
+    if (shm_error)
230118
+	goto out;
230118
+
230118
+    ximage->data = seg.shmaddr;
230118
+    ximage->obdata = &seg;
230118
+    if (!XShmGetImage(dpy, pread->xDrawable, ximage, 0, 0, -1))
230118
+	goto out;
230118
+
230118
+    /*
230118
+     * ShmGetImage doesn't actually pay attention to ->bytes_per_line.
230118
+     * We have to compensate for this somewhere since llvmpipe's natural
230118
+     * tile width is 64.  Do it here so we don't have to undo it with a
230118
+     * bunch of memmove in the driver.
230118
+     */
230118
+    do {
230118
+	int i;
230118
+	char *src = ximage->data;
230118
+	int dst_width = align(ximage->width * ximage->bits_per_pixel / 8, 256);
230118
+
230118
+	for (i = 0; i < ximage->height; i++) {
230118
+	    memcpy(data, src, ximage->bytes_per_line);
230118
+	    data += dst_width;
230118
+	    src += ximage->bytes_per_line;
230118
+	}
230118
+    } while (0);
230118
+    ret = 1;
230118
+
230118
+out:
230118
+    ximage->obdata = NULL;
230118
+    ximage->data = NULL;
230118
+    shm_error = 0;
230118
+    XShmDetach(dpy, &seg;;
230118
+    if (seg.shmaddr != (void *)-1)
230118
+	shmdt(seg.shmaddr);
230118
+    if (seg.shmid > -1)
230118
+	shmctl(seg.shmid, IPC_RMID, NULL);
230118
+    return ret;
230118
+}
230118
+
230118
 static void
230118
 swrastGetImage(__DRIdrawable * read,
230118
                int x, int y, int w, int h,
230118
@@ -220,11 +313,17 @@ swrastGetImage(__DRIdrawable * read,
230118
    readable = pread->xDrawable;
230118
 
230118
    ximage = prp->ximage;
230118
-   ximage->data = data;
230118
    ximage->width = w;
230118
    ximage->height = h;
230118
    ximage->bytes_per_line = bytes_per_line(w * ximage->bits_per_pixel, 32);
230118
 
230118
+   /* XXX check dimensions, if any caller ever sub-images */
230118
+   if (swrastShmGetImage(read, data, prp))
230118
+      return;
230118
+
230118
+   /* shm failed, fall back to protocol */
230118
+   ximage->data = data;
230118
+
230118
    XGetSubImage(dpy, readable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0);
230118
 
230118
    ximage->data = NULL;