summaryrefslogtreecommitdiffstats
path: root/mesa-8.0-llvmpipe-shmget.patch
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2012-03-22 05:29:19 -0400
committerAdam Jackson <ajax@redhat.com>2012-03-22 05:29:19 -0400
commit8851970d6f2b097ccca6ea732edc345d6d9e04cf (patch)
tree65a02bd727623ad1f0347751c79d0df0face6748 /mesa-8.0-llvmpipe-shmget.patch
parent6f9536616bad9854c91fd265f8c902f70a67c633 (diff)
downloadmesa-8851970d6f2b097ccca6ea732edc345d6d9e04cf.tar.gz
mesa-8851970d6f2b097ccca6ea732edc345d6d9e04cf.tar.xz
mesa-8851970d6f2b097ccca6ea732edc345d6d9e04cf.zip
maybe i should commit this too
Diffstat (limited to 'mesa-8.0-llvmpipe-shmget.patch')
-rw-r--r--mesa-8.0-llvmpipe-shmget.patch156
1 files changed, 156 insertions, 0 deletions
diff --git a/mesa-8.0-llvmpipe-shmget.patch b/mesa-8.0-llvmpipe-shmget.patch
new file mode 100644
index 0000000..30e27ce
--- /dev/null
+++ b/mesa-8.0-llvmpipe-shmget.patch
@@ -0,0 +1,156 @@
+diff -up Mesa-8.0.1/src/gallium/state_trackers/dri/sw/drisw.c.shmget Mesa-8.0.1/src/gallium/state_trackers/dri/sw/drisw.c
+--- Mesa-8.0.1/src/gallium/state_trackers/dri/sw/drisw.c.shmget 2012-02-14 18:44:00.000000000 -0500
++++ Mesa-8.0.1/src/gallium/state_trackers/dri/sw/drisw.c 2012-03-15 06:35:44.989221196 -0400
+@@ -252,7 +252,6 @@ drisw_update_tex_buffer(struct dri_drawa
+ struct pipe_transfer *transfer;
+ char *map;
+ int x, y, w, h;
+- int ximage_stride, line;
+
+ get_drawable_info(dPriv, &x, &y, &w, &h);
+
+@@ -265,15 +264,6 @@ drisw_update_tex_buffer(struct dri_drawa
+ /* Copy the Drawable content to the mapped texture buffer */
+ get_image(dPriv, x, y, w, h, map);
+
+- /* The pipe transfer has a pitch rounded up to the nearest 64 pixels.
+- We assume 32 bit pixels. */
+- ximage_stride = w * 4;
+- for (line = h-1; line; --line) {
+- memmove(&map[line * transfer->stride],
+- &map[line * ximage_stride],
+- ximage_stride);
+- }
+-
+ pipe_transfer_unmap(pipe, transfer);
+ pipe_transfer_destroy(pipe, transfer);
+ }
+diff -up Mesa-8.0.1/src/glx/drisw_glx.c.shmget Mesa-8.0.1/src/glx/drisw_glx.c
+--- Mesa-8.0.1/src/glx/drisw_glx.c.shmget 2012-02-14 18:44:00.000000000 -0500
++++ Mesa-8.0.1/src/glx/drisw_glx.c 2012-03-14 11:25:04.708341441 -0400
+@@ -24,6 +24,9 @@
+ #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
+
+ #include <X11/Xlib.h>
++#include <sys/ipc.h>
++#include <sys/shm.h>
++#include <X11/extensions/XShm.h>
+ #include "glxclient.h"
+ #include <dlfcn.h>
+ #include "dri_common.h"
+@@ -203,6 +206,96 @@ swrastPutImage(__DRIdrawable * draw, int
+ ximage->data = NULL;
+ }
+
++static int shm_error;
++
++static int
++shm_handler(Display *d, XErrorEvent *e)
++{
++ shm_error = 1;
++ return 0;
++}
++
++static int
++align(int value, int alignment)
++{
++ return (value + alignment - 1) & ~(alignment - 1);
++}
++
++/*
++ * Slight fast path. Short of changing how texture memory is allocated, we
++ * have two options for getting the pixels out. GetImage is clamped by the
++ * server's write buffer size, so you end up doing lots of relatively small
++ * requests (128k each or so), with two memcpys: down into the kernel, and
++ * then back up. ShmGetImage is one big blit into the shm segment (which
++ * could be GPU DMA, in principle) and then another one here.
++ */
++static Bool
++swrastShmGetImage(__DRIdrawable *read, char *data, struct drisw_drawable *prp)
++{
++ __GLXDRIdrawable *pread = &(prp->base);
++ Display *dpy = pread->psc->dpy;
++ XImage *ximage = prp->ximage;
++ unsigned long image_size = ximage->height * ximage->bytes_per_line;
++ Bool ret = 0;
++ XShmSegmentInfo seg = { 0, -1, (void *)-1, 0 };
++ int (*old_handler)(Display *, XErrorEvent *);
++
++ if (!XShmQueryExtension(dpy))
++ goto out;
++
++ /* image setup */
++ seg.shmid = shmget(IPC_PRIVATE, image_size, IPC_CREAT | 0777);
++ if (seg.shmid < 0)
++ goto out;
++
++ seg.shmaddr = shmat(seg.shmid, NULL, 0);
++ if (seg.shmaddr == (void *)-1)
++ goto out;
++
++ XSync(dpy, 0);
++ old_handler = XSetErrorHandler(shm_handler);
++ XShmAttach(dpy, &seg);
++ XSync(dpy, 0);
++ XSetErrorHandler(old_handler);
++ if (shm_error)
++ goto out;
++
++ ximage->data = seg.shmaddr;
++ ximage->obdata = &seg;
++ if (!XShmGetImage(dpy, pread->xDrawable, ximage, 0, 0, -1))
++ goto out;
++
++ /*
++ * ShmGetImage doesn't actually pay attention to ->bytes_per_line.
++ * We have to compensate for this somewhere since llvmpipe's natural
++ * tile width is 64. Do it here so we don't have to undo it with a
++ * bunch of memmove in the driver.
++ */
++ do {
++ int i;
++ char *src = ximage->data;
++ int dst_width = align(ximage->width * ximage->bits_per_pixel / 8, 128);
++
++ for (i = 0; i < ximage->height; i++) {
++ memcpy(data, src, ximage->bytes_per_line);
++ data += dst_width;
++ src += ximage->bytes_per_line;
++ }
++ } while (0);
++ ret = 1;
++
++out:
++ ximage->obdata = NULL;
++ ximage->data = NULL;
++ shm_error = 0;
++ XShmDetach(dpy, &seg);
++ if (seg.shmaddr != (void *)-1)
++ shmdt(seg.shmaddr);
++ if (seg.shmid > -1)
++ shmctl(seg.shmid, IPC_RMID, NULL);
++ return ret;
++}
++
+ static void
+ swrastGetImage(__DRIdrawable * read,
+ int x, int y, int w, int h,
+@@ -217,11 +310,17 @@ swrastGetImage(__DRIdrawable * read,
+ readable = pread->xDrawable;
+
+ ximage = prp->ximage;
+- ximage->data = data;
+ ximage->width = w;
+ ximage->height = h;
+ ximage->bytes_per_line = bytes_per_line(w * ximage->bits_per_pixel, 32);
+
++ /* XXX check dimensions, if any caller ever sub-images */
++ if (swrastShmGetImage(read, data, prp))
++ return;
++
++ /* shm failed, fall back to protocol */
++ ximage->data = data;
++
+ XGetSubImage(dpy, readable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0);
+
+ ximage->data = NULL;