summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/xlib
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2010-03-04 16:09:33 +0000
committerKeith Whitwell <keithw@vmware.com>2010-03-04 16:09:33 +0000
commit94ce4eb3c27706d992226d847d123c46b14b1c4f (patch)
tree051157b0c0a2717484e2c0e41551c1e75f0cb289 /src/gallium/winsys/xlib
parentc7f7a309af54c76eccb451aa0c4f007656ebe7e1 (diff)
softpipe: rework to use the llvmpipe winsys
Promote the llvmpipe winsys more or less unchanged to state_trackers/sw_winsys.h. Some minor breakages: - softpipe::texture_blanket is broken, but scheduled for removal anyway. - haven't fixed up g3vdl yet.
Diffstat (limited to 'src/gallium/winsys/xlib')
-rw-r--r--src/gallium/winsys/xlib/Makefile1
-rw-r--r--src/gallium/winsys/xlib/SConscript4
-rw-r--r--src/gallium/winsys/xlib/xlib.c4
-rw-r--r--src/gallium/winsys/xlib/xlib.h7
-rw-r--r--src/gallium/winsys/xlib/xlib_llvmpipe.c363
-rw-r--r--src/gallium/winsys/xlib/xlib_softpipe.c464
-rw-r--r--src/gallium/winsys/xlib/xlib_sw_winsys.c394
7 files changed, 428 insertions, 809 deletions
diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile
index 824c666ae3..129300423a 100644
--- a/src/gallium/winsys/xlib/Makefile
+++ b/src/gallium/winsys/xlib/Makefile
@@ -29,6 +29,7 @@ DEFINES += \
XLIB_WINSYS_SOURCES = \
xlib.c \
xlib_cell.c \
+ xlib_sw_winsys.c \
xlib_llvmpipe.c \
xlib_softpipe.c
diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript
index 8c9d318af2..92e508ee50 100644
--- a/src/gallium/winsys/xlib/SConscript
+++ b/src/gallium/winsys/xlib/SConscript
@@ -36,7 +36,7 @@ drivers = [trace]
if 'softpipe' in env['drivers']:
env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
- sources += ['xlib_softpipe.c']
+ sources += ['xlib_softpipe.c', 'xlib_sw_winsys.c']
drivers += [softpipe]
if 'llvmpipe' in env['drivers']:
@@ -44,7 +44,7 @@ if 'llvmpipe' in env['drivers']:
if 'LLVM_VERSION' in env:
env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
env.Tool('udis86')
- sources += ['xlib_llvmpipe.c']
+ sources += ['xlib_llvmpipe.c', 'xlib_sw_winsys.c']
drivers += [llvmpipe]
if 'cell' in env['drivers']:
diff --git a/src/gallium/winsys/xlib/xlib.c b/src/gallium/winsys/xlib/xlib.c
index 67617a470d..9b91c980d1 100644
--- a/src/gallium/winsys/xlib/xlib.c
+++ b/src/gallium/winsys/xlib/xlib.c
@@ -33,9 +33,7 @@
#include "xlib.h"
#include "xm_winsys.h"
-
-#include <stdlib.h>
-#include <assert.h>
+#include "util/u_debug.h"
/* Todo, replace all this with callback-structs provided by the
* individual implementations.
diff --git a/src/gallium/winsys/xlib/xlib.h b/src/gallium/winsys/xlib/xlib.h
index 8e091d0c08..7f9f910b88 100644
--- a/src/gallium/winsys/xlib/xlib.h
+++ b/src/gallium/winsys/xlib/xlib.h
@@ -9,5 +9,12 @@ extern struct xm_driver xlib_softpipe_driver;
extern struct xm_driver xlib_llvmpipe_driver;
extern struct xm_driver xlib_cell_driver;
+/* Internal:
+ */
+struct sw_winsys;
+struct sw_displaytarget;
+struct sw_winsys *xlib_create_sw_winsys( void );
+void xlib_sw_display(struct xmesa_buffer *xm_buffer,
+ struct sw_displaytarget *dt);
#endif
diff --git a/src/gallium/winsys/xlib/xlib_llvmpipe.c b/src/gallium/winsys/xlib/xlib_llvmpipe.c
index 6cebd4c201..9929ba52e7 100644
--- a/src/gallium/winsys/xlib/xlib_llvmpipe.c
+++ b/src/gallium/winsys/xlib/xlib_llvmpipe.c
@@ -33,367 +33,16 @@
*/
-#if defined(GALLIUM_LLVMPIPE)
-
-#include "xm_api.h"
-#undef ASSERT
-#undef Elements
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "llvmpipe/lp_winsys.h"
-#include "llvmpipe/lp_texture.h"
#include "xlib.h"
-/**
- * Subclass of pipe_buffer for Xlib winsys.
- * Low-level OS/window system memory buffer
- */
-struct xm_displaytarget
-{
- enum pipe_format format;
- unsigned width;
- unsigned height;
- unsigned stride;
-
- void *data;
- void *mapped;
-
- XImage *tempImage;
-#ifdef USE_XSHM
- int shm;
- XShmSegmentInfo shminfo;
-#endif
-};
-
-
-/**
- * Subclass of llvmpipe_winsys for Xlib winsys
- */
-struct xmesa_llvmpipe_winsys
-{
- struct llvmpipe_winsys base;
-/* struct xmesa_visual *xm_visual; */
-};
-
-
-
-/** Cast wrapper */
-static INLINE struct xm_displaytarget *
-xm_displaytarget( struct llvmpipe_displaytarget *dt )
-{
- return (struct xm_displaytarget *)dt;
-}
-
-
-/**
- * X Shared Memory Image extension code
- */
-
-#ifdef USE_XSHM
-
-static volatile int mesaXErrorFlag = 0;
-
-/**
- * Catches potential Xlib errors.
- */
-static int
-mesaHandleXError(Display *dpy, XErrorEvent *event)
-{
- (void) dpy;
- (void) event;
- mesaXErrorFlag = 1;
- return 0;
-}
-
-
-static char *alloc_shm(struct xm_displaytarget *buf, unsigned size)
-{
- XShmSegmentInfo *const shminfo = & buf->shminfo;
-
- shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
- if (shminfo->shmid < 0) {
- return NULL;
- }
-
- shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
- if (shminfo->shmaddr == (char *) -1) {
- shmctl(shminfo->shmid, IPC_RMID, 0);
- return NULL;
- }
-
- shminfo->readOnly = False;
- return shminfo->shmaddr;
-}
-
-
-/**
- * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
- */
-static void
-alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
- struct xmesa_buffer *xmb,
- unsigned width, unsigned height)
-{
- /*
- * We have to do a _lot_ of error checking here to be sure we can
- * really use the XSHM extension. It seems different servers trigger
- * errors at different points if the extension won't work. Therefore
- * we have to be very careful...
- */
- int (*old_handler)(Display *, XErrorEvent *);
-
- xm_buffer->tempImage = XShmCreateImage(xmb->xm_visual->display,
- xmb->xm_visual->visinfo->visual,
- xmb->xm_visual->visinfo->depth,
- ZPixmap,
- NULL,
- &xm_buffer->shminfo,
- width, height);
- if (xm_buffer->tempImage == NULL) {
- xm_buffer->shm = 0;
- return;
- }
-
-
- mesaXErrorFlag = 0;
- old_handler = XSetErrorHandler(mesaHandleXError);
- /* This may trigger the X protocol error we're ready to catch: */
- XShmAttach(xmb->xm_visual->display, &xm_buffer->shminfo);
- XSync(xmb->xm_visual->display, False);
-
- if (mesaXErrorFlag) {
- /* we are on a remote display, this error is normal, don't print it */
- XFlush(xmb->xm_visual->display);
- mesaXErrorFlag = 0;
- XDestroyImage(xm_buffer->tempImage);
- xm_buffer->tempImage = NULL;
- xm_buffer->shm = 0;
- (void) XSetErrorHandler(old_handler);
- return;
- }
-
- xm_buffer->shm = 1;
-}
-
-#endif /* USE_XSHM */
-
-static boolean
-xm_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
- enum pipe_format format )
-{
- /* TODO: check visuals or other sensible thing here */
- return TRUE;
-}
-
-
-static void *
-xm_displaytarget_map(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
- unsigned flags)
-{
- struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
- xm_dt->mapped = xm_dt->data;
- return xm_dt->mapped;
-}
-
-static void
-xm_displaytarget_unmap(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt)
-{
- struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
- xm_dt->mapped = NULL;
-}
-
-static void
-xm_displaytarget_destroy(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt)
-{
- struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
-
- if (xm_dt->data) {
-#ifdef USE_XSHM
- if (xm_dt->shminfo.shmid >= 0) {
- shmdt(xm_dt->shminfo.shmaddr);
- shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0);
-
- xm_dt->shminfo.shmid = -1;
- xm_dt->shminfo.shmaddr = (char *) -1;
- }
- else
-#endif
- FREE(xm_dt->data);
- }
-
- FREE(xm_dt);
-}
-
-
-/**
- * Display/copy the image in the surface into the X window specified
- * by the XMesaBuffer.
- */
-static void
-xm_llvmpipe_display(struct xmesa_buffer *xm_buffer,
- struct llvmpipe_displaytarget *dt)
-{
- XImage *ximage;
- struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
- static boolean no_swap = 0;
- static boolean firsttime = 1;
-
- if (firsttime) {
- no_swap = getenv("SP_NO_RAST") != NULL;
- firsttime = 0;
- }
-
- if (no_swap)
- return;
-
-#ifdef USE_XSHM
- if (xm_dt->shm)
- {
- if (xm_dt->tempImage == NULL)
- {
- assert(util_format_get_blockwidth(xm_dt->format) == 1);
- assert(util_format_get_blockheight(xm_dt->format) == 1);
- alloc_shm_ximage(xm_dt, xm_buffer,
- xm_dt->stride / util_format_get_blocksize(xm_dt->format),
- xm_dt->height);
- }
-
- ximage = xm_dt->tempImage;
- ximage->data = xm_dt->data;
-
- /* _debug_printf("XSHM\n"); */
- XShmPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
- ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False);
- }
- else
-#endif
- {
- /* display image in Window */
- ximage = xm_dt->tempImage;
- ximage->data = xm_dt->data;
-
- /* check that the XImage has been previously initialized */
- assert(ximage->format);
- assert(ximage->bitmap_unit);
-
- /* update XImage's fields */
- ximage->width = xm_dt->width;
- ximage->height = xm_dt->height;
- ximage->bytes_per_line = xm_dt->stride;
-
- /* _debug_printf("XPUT\n"); */
- XPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
- ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height);
- }
-}
-
-/**
- * Display/copy the image in the surface into the X window specified
- * by the XMesaBuffer.
- */
-static void
-xm_displaytarget_display(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
- void *context_private)
-{
- XMesaContext xmctx = (XMesaContext) context_private;
- struct xmesa_buffer *xm_buffer = xmctx->xm_buffer;
- xm_llvmpipe_display(xm_buffer, dt);
-}
-
-static struct llvmpipe_displaytarget *
-xm_displaytarget_create(struct llvmpipe_winsys *winsys,
- enum pipe_format format,
- unsigned width, unsigned height,
- unsigned alignment,
- unsigned *stride)
-{
- struct xm_displaytarget *xm_dt = CALLOC_STRUCT(xm_displaytarget);
- unsigned nblocksy, size;
-
- xm_dt = CALLOC_STRUCT(xm_displaytarget);
- if(!xm_dt)
- goto no_xm_dt;
-
- xm_dt->format = format;
- xm_dt->width = width;
- xm_dt->height = height;
-
- nblocksy = util_format_get_nblocksy(format, height);
- xm_dt->stride = align(util_format_get_stride(format, width), alignment);
- size = xm_dt->stride * nblocksy;
-
-#ifdef USE_XSHM
- if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
- {
- xm_dt->shminfo.shmid = -1;
- xm_dt->shminfo.shmaddr = (char *) -1;
- xm_dt->shm = TRUE;
-
- xm_dt->data = alloc_shm(xm_dt, size);
- if(!xm_dt->data)
- goto no_data;
- }
-#endif
-
- if(!xm_dt->data) {
- xm_dt->data = align_malloc(size, alignment);
- if(!xm_dt->data)
- goto no_data;
- }
-
- *stride = xm_dt->stride;
- return (struct llvmpipe_displaytarget *)xm_dt;
-
-no_data:
- FREE(xm_dt);
-no_xm_dt:
- return NULL;
-}
-
-
-static void
-xm_destroy( struct llvmpipe_winsys *ws )
-{
- FREE(ws);
-}
-
-
-static struct llvmpipe_winsys *
-xlib_create_llvmpipe_winsys( void )
-{
- struct xmesa_llvmpipe_winsys *ws;
-
- ws = CALLOC_STRUCT(xmesa_llvmpipe_winsys);
- if (!ws)
- return NULL;
-
- ws->base.destroy = xm_destroy;
-
- ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
-
- ws->base.displaytarget_create = xm_displaytarget_create;
- ws->base.displaytarget_map = xm_displaytarget_map;
- ws->base.displaytarget_unmap = xm_displaytarget_unmap;
- ws->base.displaytarget_destroy = xm_displaytarget_destroy;
-
- ws->base.displaytarget_display = xm_displaytarget_display;
-
- return &ws->base;
-}
+#if defined(GALLIUM_LLVMPIPE)
+#include "llvmpipe/lp_texture.h"
+#include "llvmpipe/lp_winsys.h"
+#include "state_tracker/sw_winsys.h"
static struct pipe_screen *
xlib_create_llvmpipe_screen( void )
@@ -401,7 +50,7 @@ xlib_create_llvmpipe_screen( void )
struct llvmpipe_winsys *winsys;
struct pipe_screen *screen;
- winsys = xlib_create_llvmpipe_winsys();
+ winsys = xlib_create_sw_winsys();
if (winsys == NULL)
return NULL;
@@ -427,7 +76,7 @@ xlib_llvmpipe_display_surface(struct xmesa_buffer *xm_buffer,
assert(texture->dt);
if (texture->dt)
- xm_llvmpipe_display(xm_buffer, texture->dt);
+ xlib_sw_display(xm_buffer, texture->dt);
}
diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c
index 716338aef4..df93de551c 100644
--- a/src/gallium/winsys/xlib/xlib_softpipe.c
+++ b/src/gallium/winsys/xlib/xlib_softpipe.c
@@ -26,461 +26,19 @@
*
**************************************************************************/
-/*
- * Authors:
- * Keith Whitwell
- * Brian Paul
- */
-
-
-#include "xm_api.h"
-
-#undef ASSERT
-#undef Elements
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "softpipe/sp_winsys.h"
-#include "softpipe/sp_texture.h"
#include "xlib.h"
-
-/**
- * Subclass of pipe_buffer for Xlib winsys.
- * Low-level OS/window system memory buffer
- */
-struct xm_buffer
-{
- struct pipe_buffer base;
- boolean userBuffer; /** Is this a user-space buffer? */
- void *data;
- void *mapped;
-
- XImage *tempImage;
-#ifdef USE_XSHM
- boolean shm; /** Is this a shared memory buffer? */
- XShmSegmentInfo shminfo;
-#endif
-};
-
-
-/**
- * Subclass of pipe_winsys for Xlib winsys
- */
-struct xmesa_pipe_winsys
-{
- struct pipe_winsys base;
-/* struct xmesa_visual *xm_visual; */
-};
-
-
-
-/** Cast wrapper */
-static INLINE struct xm_buffer *
-xm_buffer( struct pipe_buffer *buf )
-{
- return (struct xm_buffer *)buf;
-}
-
-
-/**
- * X Shared Memory Image extension code
- */
-
-#ifdef USE_XSHM
-
-static volatile int mesaXErrorFlag = 0;
-
-/**
- * Catches potential Xlib errors.
- */
-static int
-mesaHandleXError(Display *dpy, XErrorEvent *event)
-{
- (void) dpy;
- (void) event;
- mesaXErrorFlag = 1;
- return 0;
-}
-
-
-static char *alloc_shm(struct xm_buffer *buf, unsigned size)
-{
- XShmSegmentInfo *const shminfo = & buf->shminfo;
-
- shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
- if (shminfo->shmid < 0) {
- return NULL;
- }
-
- shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
- if (shminfo->shmaddr == (char *) -1) {
- shmctl(shminfo->shmid, IPC_RMID, 0);
- return NULL;
- }
-
- shminfo->readOnly = False;
- return shminfo->shmaddr;
-}
-
-
-/**
- * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
- */
-static void
-alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb,
- unsigned width, unsigned height)
-{
- /*
- * We have to do a _lot_ of error checking here to be sure we can
- * really use the XSHM extension. It seems different servers trigger
- * errors at different points if the extension won't work. Therefore
- * we have to be very careful...
- */
- int (*old_handler)(Display *, XErrorEvent *);
-
- b->tempImage = XShmCreateImage(xmb->xm_visual->display,
- xmb->xm_visual->visinfo->visual,
- xmb->xm_visual->visinfo->depth,
- ZPixmap,
- NULL,
- &b->shminfo,
- width, height);
- if (b->tempImage == NULL) {
- b->shm = FALSE;
- return;
- }
-
-
- mesaXErrorFlag = 0;
- old_handler = XSetErrorHandler(mesaHandleXError);
- /* This may trigger the X protocol error we're ready to catch: */
- XShmAttach(xmb->xm_visual->display, &b->shminfo);
- XSync(xmb->xm_visual->display, False);
-
- if (mesaXErrorFlag) {
- /* we are on a remote display, this error is normal, don't print it */
- XFlush(xmb->xm_visual->display);
- mesaXErrorFlag = 0;
- XDestroyImage(b->tempImage);
- b->tempImage = NULL;
- b->shm = FALSE;
- (void) XSetErrorHandler(old_handler);
- return;
- }
-
- b->shm = TRUE;
-}
-
-#endif /* USE_XSHM */
-
-
-
-/* Most callbacks map direcly onto dri_bufmgr operations:
- */
-static void *
-xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
- unsigned flags)
-{
- struct xm_buffer *xm_buf = xm_buffer(buf);
- xm_buf->mapped = xm_buf->data;
- return xm_buf->mapped;
-}
-
-static void
-xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
- struct xm_buffer *xm_buf = xm_buffer(buf);
- xm_buf->mapped = NULL;
-}
-
-static void
-xm_buffer_destroy(struct pipe_buffer *buf)
-{
- struct xm_buffer *oldBuf = xm_buffer(buf);
-
- /*
- * Note oldBuf->data may point to one of three things:
- * 1. XShm shared memory image data
- * 2. User-provided (wrapped) memory, see xm_user_buffer_create()
- * 3. Regular, malloc'd memory
- * We need to be careful with freeing that data now.
- */
-
- if (oldBuf->data) {
-#ifdef USE_XSHM
- if (oldBuf->shminfo.shmid >= 0) {
- shmdt(oldBuf->shminfo.shmaddr);
- shmctl(oldBuf->shminfo.shmid, IPC_RMID, 0);
-
- oldBuf->shminfo.shmid = -1;
- oldBuf->shminfo.shmaddr = (char *) -1;
- }
-
- if (oldBuf->shm) {
- oldBuf->data = NULL;
- }
-
- if (oldBuf->tempImage) {
- XDestroyImage(oldBuf->tempImage);
- oldBuf->tempImage = NULL;
- }
-#endif
-
- if (oldBuf->data && !oldBuf->userBuffer) {
- /* this was regular malloc'd memory */
- align_free(oldBuf->data);
- }
-
- oldBuf->data = NULL;
- }
-
- free(oldBuf);
-}
-
-
-/**
- * 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,
- struct pipe_surface *surf)
-{
- XImage *ximage;
- 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;
-
- if (firsttime) {
- no_swap = getenv("SP_NO_RAST") != NULL;
- firsttime = 0;
- }
-
- if (no_swap)
- return;
-
-#ifdef USE_XSHM
- if (xm_buf->shm)
- {
- if (xm_buf->tempImage == NULL)
- {
- assert(util_format_get_blockwidth(surf->texture->format) == 1);
- assert(util_format_get_blockheight(surf->texture->format) == 1);
- alloc_shm_ximage(xm_buf, b, spt->stride[surf->level] /
- util_format_get_blocksize(surf->texture->format), surf->height);
- }
-
- ximage = xm_buf->tempImage;
- ximage->data = xm_buf->data;
-
- /* _debug_printf("XSHM\n"); */
- XShmPutImage(b->xm_visual->display, b->drawable, b->gc,
- ximage, 0, 0, 0, 0, surf->width, surf->height, False);
- }
- else
-#endif
- {
- /* display image in Window */
- ximage = b->tempImage;
- ximage->data = xm_buf->data;
-
- /* check that the XImage has been previously initialized */
- assert(ximage->format);
- assert(ximage->bitmap_unit);
-
- /* update XImage's fields */
- ximage->width = surf->width;
- ximage->height = surf->height;
- ximage->bytes_per_line = spt->stride[surf->level];
-
- /* _debug_printf("XPUT\n"); */
- XPutImage(b->xm_visual->display, b->drawable, b->gc,
- ximage, 0, 0, 0, 0, surf->width, surf->height);
- }
-}
-
-
-static void
-xm_flush_frontbuffer(struct pipe_winsys *pws,
- struct pipe_surface *surf,
- void *context_private)
-{
- /*
- * The front color buffer is actually just another XImage buffer.
- * This function copies that XImage to the actual X Window.
- */
- XMesaContext xmctx = (XMesaContext) context_private;
- xlib_softpipe_display_surface(xmctx->xm_buffer, surf);
- xmesa_check_and_update_buffer_size(xmctx, xmctx->xm_buffer);
-}
-
-
-
-static const char *
-xm_get_name(struct pipe_winsys *pws)
-{
- return "Xlib";
-}
-
-
-static struct pipe_buffer *
-xm_buffer_create(struct pipe_winsys *pws,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
-
- /* align to 16-byte multiple for Cell */
- buffer->data = align_malloc(size, max(alignment, 16));
-
- return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.size = bytes;
- buffer->userBuffer = TRUE;
- buffer->data = ptr;
-
- return &buffer->base;
-}
-
-
-static struct pipe_buffer *
-xm_surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy, size;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
- size = *stride * nblocksy;
-
-#ifdef USE_XSHM
- if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
- {
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
- buffer->userBuffer = FALSE;
- buffer->shminfo.shmid = -1;
- buffer->shminfo.shmaddr = (char *) -1;
- buffer->shm = TRUE;
-
- buffer->data = alloc_shm(buffer, size);
- if (!buffer->data)
- goto out;
-
- return &buffer->base;
-
- out:
- if (buffer)
- FREE(buffer);
- }
-#endif
-
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- size);
-}
-
-
-/*
- * Fence functions - basically nothing to do, as we don't create any actual
- * fence objects.
- */
-
-static void
-xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static int
-xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-
-static struct pipe_winsys *
-xlib_create_softpipe_winsys( void )
-{
- static struct xmesa_pipe_winsys *ws = NULL;
-
- if (!ws) {
- ws = CALLOC_STRUCT(xmesa_pipe_winsys);
-
- /* Fill in this struct with callbacks that pipe will need to
- * communicate with the window system, buffer manager, etc.
- */
- ws->base.buffer_create = xm_buffer_create;
- ws->base.user_buffer_create = xm_user_buffer_create;
- ws->base.buffer_map = xm_buffer_map;
- ws->base.buffer_unmap = xm_buffer_unmap;
- ws->base.buffer_destroy = xm_buffer_destroy;
-
- ws->base.surface_buffer_create = xm_surface_buffer_create;
-
- ws->base.fence_reference = xm_fence_reference;
- ws->base.fence_signalled = xm_fence_signalled;
- ws->base.fence_finish = xm_fence_finish;
-
- ws->base.flush_frontbuffer = xm_flush_frontbuffer;
- ws->base.get_name = xm_get_name;
- }
-
- return &ws->base;
-}
-
+#include "softpipe/sp_texture.h"
+#include "softpipe/sp_screen.h"
+#include "state_tracker/sw_winsys.h"
static struct pipe_screen *
xlib_create_softpipe_screen( void )
{
- struct pipe_winsys *winsys;
+ struct sw_winsys *winsys;
struct pipe_screen *screen;
- winsys = xlib_create_softpipe_winsys();
+ winsys = xlib_create_sw_winsys();
if (winsys == NULL)
return NULL;
@@ -498,6 +56,18 @@ fail:
}
+static void
+xlib_softpipe_display_surface(struct xmesa_buffer *xm_buffer,
+ struct pipe_surface *surf)
+{
+ struct softpipe_texture *texture = softpipe_texture(surf->texture);
+
+ assert(texture->dt);
+ if (texture->dt)
+ xlib_sw_display(xm_buffer, texture->dt);
+}
+
+
struct xm_driver xlib_softpipe_driver =
{
.create_pipe_screen = xlib_create_softpipe_screen,
diff --git a/src/gallium/winsys/xlib/xlib_sw_winsys.c b/src/gallium/winsys/xlib/xlib_sw_winsys.c
new file mode 100644
index 0000000000..e4b02ba093
--- /dev/null
+++ b/src/gallium/winsys/xlib/xlib_sw_winsys.c
@@ -0,0 +1,394 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell
+ * Brian Paul
+ */
+
+
+
+#include "xm_api.h"
+
+#undef ASSERT
+#undef Elements
+
+#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "state_tracker/sw_winsys.h"
+
+#include "xlib.h"
+
+/**
+ * Subclass of pipe_buffer for Xlib winsys.
+ * Low-level OS/window system memory buffer
+ */
+struct xm_displaytarget
+{
+ enum pipe_format format;
+ unsigned width;
+ unsigned height;
+ unsigned stride;
+
+ void *data;
+ void *mapped;
+
+ XImage *tempImage;
+#ifdef USE_XSHM
+ int shm;
+ XShmSegmentInfo shminfo;
+#endif
+};
+
+
+/**
+ * Subclass of sw_winsys for Xlib winsys
+ */
+struct xmesa_sw_winsys
+{
+ struct sw_winsys base;
+/* struct xmesa_visual *xm_visual; */
+};
+
+
+
+/** Cast wrapper */
+static INLINE struct xm_displaytarget *
+xm_displaytarget( struct sw_displaytarget *dt )
+{
+ return (struct xm_displaytarget *)dt;
+}
+
+
+/**
+ * X Shared Memory Image extension code
+ */
+
+#ifdef USE_XSHM
+
+static volatile int mesaXErrorFlag = 0;
+
+/**
+ * Catches potential Xlib errors.
+ */
+static int
+mesaHandleXError(Display *dpy, XErrorEvent *event)
+{
+ (void) dpy;
+ (void) event;
+ mesaXErrorFlag = 1;
+ return 0;
+}
+
+
+static char *alloc_shm(struct xm_displaytarget *buf, unsigned size)
+{
+ XShmSegmentInfo *const shminfo = & buf->shminfo;
+
+ shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
+ if (shminfo->shmid < 0) {
+ return NULL;
+ }
+
+ shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
+ if (shminfo->shmaddr == (char *) -1) {
+ shmctl(shminfo->shmid, IPC_RMID, 0);
+ return NULL;
+ }
+
+ shminfo->readOnly = False;
+ return shminfo->shmaddr;
+}
+
+
+/**
+ * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
+ */
+static void
+alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
+ struct xmesa_buffer *xmb,
+ unsigned width, unsigned height)
+{
+ /*
+ * We have to do a _lot_ of error checking here to be sure we can
+ * really use the XSHM extension. It seems different servers trigger
+ * errors at different points if the extension won't work. Therefore
+ * we have to be very careful...
+ */
+ int (*old_handler)(Display *, XErrorEvent *);
+
+ xm_buffer->tempImage = XShmCreateImage(xmb->xm_visual->display,
+ xmb->xm_visual->visinfo->visual,
+ xmb->xm_visual->visinfo->depth,
+ ZPixmap,
+ NULL,
+ &xm_buffer->shminfo,
+ width, height);
+ if (xm_buffer->tempImage == NULL) {
+ xm_buffer->shm = 0;
+ return;
+ }
+
+
+ mesaXErrorFlag = 0;
+ old_handler = XSetErrorHandler(mesaHandleXError);
+ /* This may trigger the X protocol error we're ready to catch: */
+ XShmAttach(xmb->xm_visual->display, &xm_buffer->shminfo);
+ XSync(xmb->xm_visual->display, False);
+
+ if (mesaXErrorFlag) {
+ /* we are on a remote display, this error is normal, don't print it */
+ XFlush(xmb->xm_visual->display);
+ mesaXErrorFlag = 0;
+ XDestroyImage(xm_buffer->tempImage);
+ xm_buffer->tempImage = NULL;
+ xm_buffer->shm = 0;
+ (void) XSetErrorHandler(old_handler);
+ return;
+ }
+
+ xm_buffer->shm = 1;
+}
+
+#endif /* USE_XSHM */
+
+static boolean
+xm_is_displaytarget_format_supported( struct sw_winsys *ws,
+ enum pipe_format format )
+{
+ /* TODO: check visuals or other sensible thing here */
+ return TRUE;
+}
+
+
+static void *
+xm_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags)
+{
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+ xm_dt->mapped = xm_dt->data;
+ return xm_dt->mapped;
+}
+
+static void
+xm_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+ xm_dt->mapped = NULL;
+}
+
+static void
+xm_displaytarget_destroy(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+
+ if (xm_dt->data) {
+#ifdef USE_XSHM
+ if (xm_dt->shminfo.shmid >= 0) {
+ shmdt(xm_dt->shminfo.shmaddr);
+ shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0);
+
+ xm_dt->shminfo.shmid = -1;
+ xm_dt->shminfo.shmaddr = (char *) -1;
+ }
+ else
+#endif
+ FREE(xm_dt->data);
+ }
+
+ FREE(xm_dt);
+}
+
+
+/**
+ * Display/copy the image in the surface into the X window specified
+ * by the XMesaBuffer.
+ */
+void
+xlib_sw_display(struct xmesa_buffer *xm_buffer,
+ struct sw_displaytarget *dt)
+{
+ XImage *ximage;
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+ static boolean no_swap = 0;
+ static boolean firsttime = 1;
+
+ if (firsttime) {
+ no_swap = getenv("SP_NO_RAST") != NULL;
+ firsttime = 0;
+ }
+
+ if (no_swap)
+ return;
+
+#ifdef USE_XSHM
+ if (xm_dt->shm)
+ {
+ if (xm_dt->tempImage == NULL)
+ {
+ assert(util_format_get_blockwidth(xm_dt->format) == 1);
+ assert(util_format_get_blockheight(xm_dt->format) == 1);
+ alloc_shm_ximage(xm_dt, xm_buffer,
+ xm_dt->stride / util_format_get_blocksize(xm_dt->format),
+ xm_dt->height);
+ }
+
+ ximage = xm_dt->tempImage;
+ ximage->data = xm_dt->data;
+
+ /* _debug_printf("XSHM\n"); */
+ XShmPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
+ ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False);
+ }
+ else
+#endif
+ {
+ /* display image in Window */
+ ximage = xm_dt->tempImage;
+ ximage->data = xm_dt->data;
+
+ /* check that the XImage has been previously initialized */
+ assert(ximage->format);
+ assert(ximage->bitmap_unit);
+
+ /* update XImage's fields */
+ ximage->width = xm_dt->width;
+ ximage->height = xm_dt->height;
+ ximage->bytes_per_line = xm_dt->stride;
+
+ /* _debug_printf("XPUT\n"); */
+ XPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
+ ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height);
+ }
+}
+
+/**
+ * Display/copy the image in the surface into the X window specified
+ * by the XMesaBuffer.
+ */
+static void
+xm_displaytarget_display(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ void *context_private)
+{
+ XMesaContext xmctx = (XMesaContext) context_private;
+ struct xmesa_buffer *xm_buffer = xmctx->xm_buffer;
+ xm_sw_display(xm_buffer, dt);
+}
+
+
+static struct sw_displaytarget *
+xm_displaytarget_create(struct sw_winsys *winsys,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct xm_displaytarget *xm_dt = CALLOC_STRUCT(xm_displaytarget);
+ unsigned nblocksy, size;
+
+ xm_dt = CALLOC_STRUCT(xm_displaytarget);
+ if(!xm_dt)
+ goto no_xm_dt;
+
+ xm_dt->format = format;
+ xm_dt->width = width;
+ xm_dt->height = height;
+
+ nblocksy = util_format_get_nblocksy(format, height);
+ xm_dt->stride = align(util_format_get_stride(format, width), alignment);
+ size = xm_dt->stride * nblocksy;
+
+#ifdef USE_XSHM
+ if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
+ {
+ xm_dt->shminfo.shmid = -1;
+ xm_dt->shminfo.shmaddr = (char *) -1;
+ xm_dt->shm = TRUE;
+
+ xm_dt->data = alloc_shm(xm_dt, size);
+ if(!xm_dt->data)
+ goto no_data;
+ }
+#endif
+
+ if(!xm_dt->data) {
+ xm_dt->data = align_malloc(size, alignment);
+ if(!xm_dt->data)
+ goto no_data;
+ }
+
+ *stride = xm_dt->stride;
+ return (struct sw_displaytarget *)xm_dt;
+
+no_data:
+ FREE(xm_dt);
+no_xm_dt:
+ return NULL;
+}
+
+
+static void
+xm_destroy( struct sw_winsys *ws )
+{
+ FREE(ws);
+}
+
+
+struct sw_winsys *
+xlib_create_sw_winsys( void )
+{
+ struct xmesa_sw_winsys *ws;
+
+ ws = CALLOC_STRUCT(xmesa_sw_winsys);
+ if (!ws)
+ return NULL;
+
+ ws->base.destroy = xm_destroy;
+
+ ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
+
+ ws->base.displaytarget_create = xm_displaytarget_create;
+ ws->base.displaytarget_map = xm_displaytarget_map;
+ ws->base.displaytarget_unmap = xm_displaytarget_unmap;
+ ws->base.displaytarget_destroy = xm_displaytarget_destroy;
+
+ ws->base.displaytarget_display = xm_displaytarget_display;
+
+ return &ws->base;
+}
+