Mesa (softpipe-private-winsys): softpipe: propogate softpipe winsys changes out to drivers
Keith Whitwell
keithw at kemper.freedesktop.org
Wed Aug 19 16:01:07 UTC 2009
Module: Mesa
Branch: softpipe-private-winsys
Commit: f0bf7b6be9f7f22ef44f991274027bd23a28ddb6
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=f0bf7b6be9f7f22ef44f991274027bd23a28ddb6
Author: Keith Whitwell <keithw at vmware.com>
Date: Wed Aug 19 16:58:33 2009 +0100
softpipe: propogate softpipe winsys changes out to drivers
Create two helper mechanisms for creating softpipe_winsys objects,
either wrapping a legacy pipe_winsys, or creating a freestanding
malloc-based winsys, and migrate drivers onto them.
---
src/gallium/drivers/softpipe/Makefile | 4 +-
src/gallium/drivers/softpipe/sp_screen_buffer.c | 3 +-
src/gallium/drivers/softpipe/sp_screen_texture.c | 13 +-
src/gallium/drivers/softpipe/sp_winsys.h | 39 +++-
src/gallium/drivers/softpipe/sp_winsys_malloc.c | 169 ++++++++++++++
src/gallium/drivers/softpipe/sp_winsys_wrapped.c | 199 ++++++++++++++++
src/gallium/state_trackers/dri/dri_screen.h | 1 -
src/gallium/winsys/drm/intel/gem/intel_be_device.c | 4 +-
src/gallium/winsys/drm/radeon/core/radeon_drm.c | 4 +-
.../drm/radeon/core/radeon_winsys_softpipe.c | 5 +-
src/gallium/winsys/egl_xlib/Makefile | 3 +-
src/gallium/winsys/egl_xlib/egl_xlib.c | 57 +++---
src/gallium/winsys/egl_xlib/sw_winsys.c | 243 --------------------
src/gallium/winsys/egl_xlib/sw_winsys.h | 40 ----
src/gallium/winsys/g3dvl/xsp_winsys.c | 92 +-------
src/gallium/winsys/xlib/xlib_softpipe.c | 94 +++++---
16 files changed, 525 insertions(+), 445 deletions(-)
diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile
index b1cbb43..4a6dddb 100644
--- a/src/gallium/drivers/softpipe/Makefile
+++ b/src/gallium/drivers/softpipe/Makefile
@@ -40,6 +40,8 @@ C_SOURCES = \
sp_state_vertex.c \
sp_tex_sample.c \
sp_tile_cache.c \
- sp_surface.c
+ sp_surface.c \
+ sp_winsys_malloc.c \
+ sp_winsys_wrapped.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/softpipe/sp_screen_buffer.c b/src/gallium/drivers/softpipe/sp_screen_buffer.c
index 068efc9..589d53c 100644
--- a/src/gallium/drivers/softpipe/sp_screen_buffer.c
+++ b/src/gallium/drivers/softpipe/sp_screen_buffer.c
@@ -86,9 +86,10 @@ softpipe_buffer_map(struct pipe_screen *screen,
if (sbuf->mem)
return sbuf->mem;
- else
+ else {
return sp_winsys->display_buffer_map( sp_winsys,
sbuf->display_buf );
+ }
}
diff --git a/src/gallium/drivers/softpipe/sp_screen_texture.c b/src/gallium/drivers/softpipe/sp_screen_texture.c
index 023eebd..1432304 100644
--- a/src/gallium/drivers/softpipe/sp_screen_texture.c
+++ b/src/gallium/drivers/softpipe/sp_screen_texture.c
@@ -381,10 +381,15 @@ softpipe_flush_frontbuffer(struct pipe_screen *screen,
void *context_private)
{
struct softpipe_winsys *sp_winsys = softpipe_screen(screen)->sp_winsys;
-
- sp_winsys->flush_frontbuffer( sp_winsys,
- surf,
- context_private );
+ struct softpipe_display_buffer *sp_disp;
+
+ sp_disp = softpipe_surface_display_buffer( surf );
+
+ if (sp_disp) {
+ sp_winsys->flush_frontbuffer( sp_winsys,
+ sp_disp,
+ context_private );
+ }
}
diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h
index 0c419b9..3c09417 100644
--- a/src/gallium/drivers/softpipe/sp_winsys.h
+++ b/src/gallium/drivers/softpipe/sp_winsys.h
@@ -52,6 +52,9 @@ struct pipe_context *softpipe_create( struct pipe_screen * );
struct softpipe_display_buffer
{
unsigned size;
+ unsigned width;
+ unsigned height;
+ enum pipe_format format;
unsigned stride;
};
@@ -61,12 +64,12 @@ struct softpipe_winsys {
void (*destroy)( struct softpipe_winsys * );
/**
- * Copy our fake pipe_surface frontbuffer to the actual window.
- * The void * pointer is likely to be an opaque handle to the
- * window.
+ * Copy our softpipe_display_buffer frontbuffer to the actual
+ * window. The void * pointer is likely to be an opaque handle to
+ * the window.
*/
void (*flush_frontbuffer)( struct softpipe_winsys *ws,
- struct pipe_surface *surf,
+ struct softpipe_display_buffer *buf,
void *context_priv ); /* the window, presumably */
/**
@@ -109,6 +112,34 @@ struct softpipe_display_buffer *
softpipe_surface_display_buffer( struct pipe_surface *surface );
+
+/* Some winsys's need to do this for one reason or another:
+ */
+boolean
+softpipe_get_texture_buffer( struct pipe_texture *texture,
+ struct pipe_buffer **buf,
+ unsigned *stride );
+
+
+/* Helper: create a malloc-based softpipe_winsys which calls out to a
+ * provided version of flush_frontbuffer.
+ */
+struct softpipe_winsys *
+softpipe_create_malloc_winsys(
+ unsigned struct_size,
+ void (*flush_frontbuffer)( struct softpipe_winsys *ws,
+ struct softpipe_display_buffer *buf,
+ void *priv ));
+
+
+/* Helper: create a softpipe_winsys which wraps a legacy pipe_winsys
+ * struct and calls out to a provided version of flush_frontbuffer.
+ */
+struct softpipe_winsys *
+softpipe_create_wrapped_winsys( struct pipe_winsys *wrapped );
+
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/drivers/softpipe/sp_winsys_malloc.c b/src/gallium/drivers/softpipe/sp_winsys_malloc.c
new file mode 100644
index 0000000..2006d42
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_winsys_malloc.c
@@ -0,0 +1,169 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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 above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+/**
+ * Helper for softpipe winsys layers - create a softpipe_winsys struct
+ * which wraps the legacy pipe_winsys structure to provide display
+ * buffers. Requires the creator to provide the pipe_winsys struct
+ * and also a flush_frontbuffer() implementation.
+ *
+ * Authors: Brian Paul
+ */
+
+
+#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "sp_winsys.h"
+
+
+struct softpipe_malloc_winsys
+{
+ struct softpipe_winsys base;
+};
+
+
+struct softpipe_malloc_display_buffer
+{
+ struct softpipe_display_buffer base;
+ void *data;
+};
+
+
+static INLINE struct softpipe_malloc_display_buffer *
+softpipe_malloc_display_buffer(struct softpipe_display_buffer *b)
+{
+ return (struct softpipe_malloc_display_buffer *) b;
+}
+
+
+static void *
+malloc_buffer_map(struct softpipe_winsys *pws,
+ struct softpipe_display_buffer *buf)
+{
+ struct softpipe_malloc_display_buffer *buffer =
+ softpipe_malloc_display_buffer(buf);
+ return buffer->data;
+}
+
+
+static void
+malloc_buffer_unmap(struct softpipe_winsys *pws,
+ struct softpipe_display_buffer *buf)
+{
+}
+
+
+static void
+malloc_buffer_destroy(struct softpipe_winsys *pws,
+ struct softpipe_display_buffer *buf)
+{
+ struct softpipe_malloc_display_buffer *buffer =
+ softpipe_malloc_display_buffer(buf);
+ align_free(buffer->data);
+ FREE(buffer);
+}
+
+
+static struct softpipe_display_buffer *
+malloc_buffer_create(struct softpipe_winsys *winsys,
+ unsigned width,
+ unsigned height,
+ enum pipe_format format,
+ unsigned usage,
+ unsigned tex_usage,
+ unsigned *stride)
+{
+ struct softpipe_malloc_display_buffer *buffer;
+ struct pipe_format_block block;
+ unsigned nblocksx, nblocksy;
+
+ buffer = CALLOC_STRUCT(softpipe_malloc_display_buffer);
+ if (!buffer)
+ return NULL;
+
+ pf_get_block(format, &block);
+ nblocksx = pf_get_nblocksx(&block, width);
+ nblocksy = pf_get_nblocksy(&block, height);
+ *stride = align(nblocksx * block.size, 16);
+
+ buffer->base.stride = *stride;
+ buffer->base.size = *stride * height;
+ buffer->base.width = width;
+ buffer->base.height = height;
+ buffer->base.format = format;
+
+ buffer->data = align_malloc( buffer->base.size, 16 );
+ if (buffer->data == NULL) {
+ FREE(buffer);
+ return NULL;
+ }
+
+ return &buffer->base;
+}
+
+static void
+malloc_winsys_destroy( struct softpipe_winsys *ws )
+{
+ FREE(ws);
+}
+
+/* The caller needs to provide a flush_frontbuffer implementation to
+ * perform the actual copy to visible window. This code knows nothing
+ * about the window system, etc, and just provides a regular memory
+ * buffer to receive softpipe rendering.
+ */
+struct softpipe_winsys *
+softpipe_create_malloc_winsys(
+ unsigned struct_size,
+ void (*flush_frontbuffer)( struct softpipe_winsys *ws,
+ struct softpipe_display_buffer *buf,
+ void *priv ))
+{
+ struct softpipe_malloc_winsys *ws;
+
+ if (struct_size < sizeof *ws) {
+ assert(0);
+ return NULL;
+ }
+
+ ws = MALLOC(struct_size);
+ if (!ws)
+ return NULL;
+
+ memset(ws, 0, struct_size);
+ ws->base.display_buffer_create = malloc_buffer_create;
+ ws->base.display_buffer_map = malloc_buffer_map;
+ ws->base.display_buffer_unmap = malloc_buffer_unmap;
+ ws->base.display_buffer_destroy = malloc_buffer_destroy;
+ ws->base.flush_frontbuffer = flush_frontbuffer;
+ ws->base.destroy = malloc_winsys_destroy;
+
+ return &ws->base;
+}
diff --git a/src/gallium/drivers/softpipe/sp_winsys_wrapped.c b/src/gallium/drivers/softpipe/sp_winsys_wrapped.c
new file mode 100644
index 0000000..f56ccbf
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_winsys_wrapped.c
@@ -0,0 +1,199 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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 above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+/**
+ * Helper for softpipe winsys layers - create a softpipe_winsys struct
+ * which wraps a pre-existing pipe_winsys struct.
+ *
+ * This is useful for hardware drivers that are still using
+ * pipe_winsys as their backend interface and want to have the option
+ * of creating a softpipe instance targetting the same backend.
+ *
+ * Authors: Keith Whitwell
+ */
+
+
+#include "pipe/p_state.h"
+#include "pipe/internal/p_winsys_screen.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "sp_winsys.h"
+
+
+/** Subclass of softpipe_winsys */
+struct softpipe_wrap_winsys
+{
+ struct softpipe_winsys base;
+ struct pipe_winsys *wrapped;
+ /* no extra fields for now */
+};
+
+
+struct softpipe_wrap_display_buffer
+{
+ struct softpipe_display_buffer base;
+ struct pipe_buffer *wrapped;
+};
+
+static INLINE struct pipe_winsys *
+get_wrapped_winsys(struct softpipe_winsys *ws)
+{
+ struct softpipe_wrap_winsys *wws =
+ (struct softpipe_wrap_winsys *)ws;
+
+ return wws->wrapped;
+}
+
+
+static INLINE struct softpipe_wrap_display_buffer *
+softpipe_wrap_display_buffer(struct softpipe_display_buffer *b)
+{
+ return (struct softpipe_wrap_display_buffer *) b;
+}
+
+
+static void *
+wrap_buffer_map(struct softpipe_winsys *spws,
+ struct softpipe_display_buffer *buf)
+{
+ struct pipe_winsys *wrapped = get_wrapped_winsys(spws);
+ struct softpipe_wrap_display_buffer *buffer =
+ softpipe_wrap_display_buffer(buf);
+
+ return wrapped->buffer_map( wrapped,
+ buffer->wrapped,
+ 0 );
+}
+
+
+static void
+wrap_buffer_unmap(struct softpipe_winsys *spws,
+ struct softpipe_display_buffer *buf)
+{
+ struct pipe_winsys *wrapped = get_wrapped_winsys(spws);
+ struct softpipe_wrap_display_buffer *buffer =
+ softpipe_wrap_display_buffer(buf);
+
+ wrapped->buffer_unmap( wrapped,
+ buffer->wrapped );
+}
+
+
+static void
+wrap_buffer_destroy(struct softpipe_winsys *spws,
+ struct softpipe_display_buffer *buf)
+{
+ struct pipe_winsys *wrapped = get_wrapped_winsys(spws);
+ struct softpipe_wrap_display_buffer *buffer =
+ softpipe_wrap_display_buffer(buf);
+ struct pipe_buffer *old_buf = buffer->wrapped;
+
+ /* Can't use pipe_buffer_reference as there probably isn't a valid
+ * screen pointer in these wrapped buffers.
+ */
+ if (pipe_reference((struct pipe_reference **)&buffer->wrapped, NULL))
+ wrapped->buffer_destroy(old_buf);
+
+ FREE(buffer);
+}
+
+
+static struct softpipe_display_buffer *
+wrap_buffer_create(struct softpipe_winsys *spws,
+ unsigned width,
+ unsigned height,
+ enum pipe_format format,
+ unsigned usage,
+ unsigned tex_usage,
+ unsigned *stride)
+{
+ struct pipe_winsys *wrapped = get_wrapped_winsys(spws);
+ struct softpipe_wrap_display_buffer *buffer;
+
+ buffer = CALLOC_STRUCT(softpipe_wrap_display_buffer);
+ if (!buffer)
+ return NULL;
+
+ buffer->wrapped = wrapped->surface_buffer_create( wrapped,
+ width,
+ height,
+ format,
+ usage,
+ tex_usage,
+ stride );
+
+ buffer->base.size = height * *stride;
+ buffer->base.width = width;
+ buffer->base.height = height;
+ buffer->base.format = format;
+ buffer->base.stride = *stride;
+
+
+ if (buffer->wrapped == NULL)
+ goto fail;
+
+ return &buffer->base;
+
+fail:
+ if (buffer && buffer->wrapped)
+ wrapped->buffer_destroy(buffer->wrapped);
+ FREE(buffer);
+ return NULL;
+}
+
+static void
+wrap_winsys_destroy( struct softpipe_winsys *spws )
+{
+ /* No destroy notifier in pipe_winsys, so not much to do.
+ */
+ FREE(spws);
+}
+
+/**
+ * Create/return a new softpipe_winsys object.
+ */
+struct softpipe_winsys *
+softpipe_create_wrapped_winsys( struct pipe_winsys *wrapped )
+{
+ struct softpipe_wrap_winsys *ws = CALLOC_STRUCT(softpipe_wrap_winsys);
+ if (!ws)
+ return NULL;
+
+ /* Fill in this struct with callbacks that pipe will need to
+ * communicate with the window system, buffer manager, etc.
+ */
+ ws->base.display_buffer_create = wrap_buffer_create;
+ ws->base.display_buffer_map = wrap_buffer_map;
+ ws->base.display_buffer_unmap = wrap_buffer_unmap;
+ ws->base.display_buffer_destroy = wrap_buffer_destroy;
+ ws->base.destroy = wrap_winsys_destroy;
+
+ ws->wrapped = wrapped;
+
+ return &ws->base;
+}
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index f6c56d0..d65902a 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -55,7 +55,6 @@ struct dri_screen
/* gallium */
struct drm_api *api;
- struct pipe_winsys *pipe_winsys;
struct pipe_screen *pipe_screen;
boolean d_depth_bits_last;
boolean sd_depth_bits_last;
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
index 5312865..385350e 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
@@ -430,7 +430,9 @@ intel_be_create_screen(struct drm_api *api, int drmFD,
intel_be_init_device(dev, drmFD, deviceID);
if (dev->softpipe) {
- screen = softpipe_create_screen(&dev->base);
+ struct softpipe_winsys *sp_winsys;
+ sp_winsys = softpipe_create_wrapped_winsys(&dev->base);
+ screen = softpipe_create_screen(sp_winsys);
} else
screen = i915_create_screen(&dev->base, deviceID);
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
index 1cfa857..25924ef 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
@@ -38,7 +38,9 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api,
struct radeon_winsys* winsys = radeon_pipe_winsys(drmFB);
if (getenv("RADEON_SOFTPIPE")) {
- return NULL; //softpipe_create_screen((struct pipe_winsys*)winsys);
+ struct softpipe_winsys *sp_winsys;
+ sp_winsys = softpipe_create_wrapped_winsys(&dev->base);
+ return softpipe_create_screen(sp_winsys);
} else {
struct r300_winsys* r300 = radeon_create_r300_winsys(drmFB, winsys);
FREE(winsys);
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c b/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c
index f038bfa..1baaec3 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c
@@ -34,8 +34,11 @@
struct pipe_context *radeon_create_softpipe(struct pipe_winsys* winsys)
{
struct pipe_screen *pipe_screen;
+ struct softpipe_winsys *sp_winsys;
- pipe_screen = softpipe_create_screen(winsys);
+ sp_winsys = softpipe_create_wrapped_winsys(&dev->base);
+
+ pipe_screen = softpipe_create_screen(sp_winsys);
return softpipe_create(pipe_screen);
}
diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile
index a33a50e..80adeab 100644
--- a/src/gallium/winsys/egl_xlib/Makefile
+++ b/src/gallium/winsys/egl_xlib/Makefile
@@ -20,8 +20,7 @@ INCLUDE_DIRS = \
-I$(TOP)/src/gallium/auxiliary
WINSYS_SOURCES = \
- egl_xlib.c \
- sw_winsys.c
+ egl_xlib.c
WINSYS_OBJECTS = $(WINSYS_SOURCES:.c=.o)
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
index f409a3f..8abfb57 100644
--- a/src/gallium/winsys/egl_xlib/egl_xlib.c
+++ b/src/gallium/winsys/egl_xlib/egl_xlib.c
@@ -38,10 +38,8 @@
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
#include "pipe/p_state.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "util/u_memory.h"
#include "softpipe/sp_winsys.h"
-#include "softpipe/sp_texture.h"
#include "eglconfig.h"
#include "eglconfigutil.h"
@@ -54,15 +52,12 @@
#include "state_tracker/st_public.h"
-#include "sw_winsys.h"
-
-
/** subclass of _EGLDriver */
struct xlib_egl_driver
{
_EGLDriver Base; /**< base class */
- struct pipe_winsys *winsys;
+ struct softpipe_winsys *sp_winsys;
struct pipe_screen *screen;
};
@@ -88,7 +83,7 @@ struct xlib_egl_surface
GC Gc;
XVisualInfo VisInfo;
- struct pipe_winsys *winsys;
+ struct softpipe_winsys *sp_winsys;
struct st_framebuffer *Framebuffer;
};
@@ -282,11 +277,10 @@ check_and_update_buffer_size(struct xlib_egl_surface *surface)
static void
-display_surface(struct pipe_winsys *pws,
- struct pipe_surface *psurf,
+display_surface(struct softpipe_winsys *spws,
+ struct softpipe_display_buffer *sp_disp,
struct xlib_egl_surface *xsurf)
{
- struct softpipe_texture *spt = softpipe_texture(psurf->texture);
XImage *ximage;
void *data;
@@ -306,35 +300,37 @@ display_surface(struct pipe_winsys *pws,
assert(ximage->format);
assert(ximage->bitmap_unit);
- data = pws->buffer_map(pws, spt->buffer, 0);
+ data = spws->display_buffer_map(spws, sp_disp);
/* update XImage's fields */
ximage->data = data;
- ximage->width = psurf->width;
- ximage->height = psurf->height;
- ximage->bytes_per_line = spt->stride[psurf->level];
+ ximage->width = sp_disp->width;
+ ximage->height = sp_disp->height;
+ ximage->bytes_per_line = sp_disp->stride;
XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc,
- ximage, 0, 0, 0, 0, psurf->width, psurf->height);
+ ximage, 0, 0, 0, 0,
+ sp_disp->width,
+ sp_disp->height);
XSync(xsurf->Dpy, 0);
ximage->data = NULL;
XDestroyImage(ximage);
- pws->buffer_unmap(pws, spt->buffer);
+ spws->display_buffer_unmap(spws, sp_disp);
}
/** Display gallium surface in X window */
static void
-flush_frontbuffer(struct pipe_winsys *pws,
- struct pipe_surface *psurf,
+flush_frontbuffer(struct softpipe_winsys *spws,
+ struct softpipe_display_buffer *psurf,
void *context_private)
{
struct xlib_egl_surface *xsurf = (struct xlib_egl_surface *) context_private;
- display_surface(pws, psurf, xsurf);
+ display_surface(spws, psurf, xsurf);
}
@@ -520,7 +516,7 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
surf->Dpy = disp->Xdpy; /* The X display */
surf->Gc = XCreateGC(surf->Dpy, surf->Win, 0, NULL);
- surf->winsys = xdrv->winsys;
+ surf->sp_winsys = xdrv->sp_winsys;
_eglConfigToContextModesRec(conf, &visual);
get_drawable_size(surf->Dpy, surf->Win, &width, &height);
@@ -603,7 +599,7 @@ xlib_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
return EGL_NO_SURFACE;
}
- surf->winsys = xdrv->winsys;
+ surf->sp_winsys = xdrv->sp_winsys;
_eglConfigToContextModesRec(conf, &visual);
@@ -730,15 +726,19 @@ xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
{
struct xlib_egl_surface *xsurf = lookup_surface(draw);
- struct pipe_winsys *pws = xsurf->winsys;
+ struct softpipe_winsys *spws = xsurf->sp_winsys;
struct pipe_surface *psurf;
+ struct softpipe_display_buffer *sp_disp;
st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT,
&psurf);
st_notify_swapbuffers(xsurf->Framebuffer);
- display_surface(pws, psurf, xsurf);
+ sp_disp = softpipe_surface_display_buffer( psurf );
+
+ if (sp_disp)
+ display_surface(spws, sp_disp, xsurf);
check_and_update_buffer_size(xsurf);
}
@@ -823,11 +823,14 @@ _eglMain(_EGLDisplay *dpy, const char *args)
xdrv->Base.Name = "Xlib/softpipe";
- /* create one winsys and use it for all contexts/surfaces */
- xdrv->winsys = create_sw_winsys();
- xdrv->winsys->flush_frontbuffer = flush_frontbuffer;
+ /* Create a generic (malloc-based) softpipe winsys using the helper
+ * code in softpipe and our implementation of flush_frontbuffer:
+ */
+ xdrv->sp_winsys = softpipe_create_malloc_winsys(
+ sizeof(struct softpipe_winsys),
+ flush_frontbuffer );
- xdrv->screen = softpipe_create_screen(xdrv->winsys);
+ xdrv->screen = softpipe_create_screen(xdrv->sp_winsys);
return &xdrv->Base;
}
diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c
deleted file mode 100644
index 79ff2cc..0000000
--- a/src/gallium/winsys/egl_xlib/sw_winsys.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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 above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * 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 TUNGSTEN GRAPHICS 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.
- *
- **************************************************************************/
-
-/**
- * Totally software-based winsys layer.
- * Note that the one winsys function that we can't implement here
- * is flush_frontbuffer().
- * Whoever uses this code will have to provide that.
- *
- * Authors: Brian Paul
- */
-
-
-#include "pipe/internal/p_winsys_screen.h"
-#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-
-#include "sw_winsys.h"
-
-
-
-/** Subclass of pipe_winsys */
-struct sw_pipe_winsys
-{
- struct pipe_winsys Base;
- /* no extra fields for now */
-};
-
-
-/** subclass of pipe_buffer */
-struct sw_pipe_buffer
-{
- struct pipe_buffer Base;
- boolean UserBuffer; /** Is this a user-space buffer? */
- void *Data;
- void *Mapped;
-};
-
-
-/** cast wrapper */
-static INLINE struct sw_pipe_buffer *
-sw_pipe_buffer(struct pipe_buffer *b)
-{
- return (struct sw_pipe_buffer *) b;
-}
-
-
-/**
- * Round n up to next multiple.
- */
-static INLINE unsigned
-round_up(unsigned n, unsigned multiple)
-{
- return (n + multiple - 1) & ~(multiple - 1);
-}
-
-
-static const char *
-get_name(struct pipe_winsys *pws)
-{
- return "software";
-}
-
-
-/** Create new pipe_buffer and allocate storage of given size */
-static struct pipe_buffer *
-buffer_create(struct pipe_winsys *pws,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
- if (!buffer)
- return NULL;
-
- 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, MAX2(alignment, 16));
-
- return &buffer->Base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
- struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
- if (!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->Base.reference, 1);
- buffer->Base.size = bytes;
- buffer->UserBuffer = TRUE;
- buffer->Data = ptr;
-
- return &buffer->Base;
-}
-
-
-static void *
-buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
- buffer->Mapped = buffer->Data;
- return buffer->Mapped;
-}
-
-
-static void
-buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
- buffer->Mapped = NULL;
-}
-
-
-static void
-buffer_destroy(struct pipe_buffer *buf)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
-
- if (buffer->Data && !buffer->UserBuffer) {
- align_free(buffer->Data);
- buffer->Data = NULL;
- }
-
- free(buffer);
-}
-
-
-static struct pipe_buffer *
-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;
- struct pipe_format_block block;
- unsigned nblocksx, nblocksy;
-
- pf_get_block(format, &block);
- nblocksx = pf_get_nblocksx(&block, width);
- nblocksy = pf_get_nblocksy(&block, height);
- *stride = round_up(nblocksx * block.size, alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- *stride * nblocksy);
-}
-
-
-static void
-fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
- /* no-op */
-}
-
-
-static int
-fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- /* no-op */
- return 0;
-}
-
-
-static int
-fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- /* no-op */
- return 0;
-}
-
-
-/**
- * Create/return a new pipe_winsys object.
- */
-struct pipe_winsys *
-create_sw_winsys(void)
-{
- struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys);
- if (!ws)
- return NULL;
-
- /* Fill in this struct with callbacks that pipe will need to
- * communicate with the window system, buffer manager, etc.
- */
- ws->Base.buffer_create = buffer_create;
- ws->Base.user_buffer_create = user_buffer_create;
- ws->Base.buffer_map = buffer_map;
- ws->Base.buffer_unmap = buffer_unmap;
- ws->Base.buffer_destroy = buffer_destroy;
-
- ws->Base.surface_buffer_create = surface_buffer_create;
-
- ws->Base.fence_reference = fence_reference;
- ws->Base.fence_signalled = fence_signalled;
- ws->Base.fence_finish = fence_finish;
-
- ws->Base.flush_frontbuffer = NULL; /* not implemented here! */
-
- ws->Base.get_name = get_name;
-
- return &ws->Base;
-}
diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.h b/src/gallium/winsys/egl_xlib/sw_winsys.h
deleted file mode 100644
index f96c5a1..0000000
--- a/src/gallium/winsys/egl_xlib/sw_winsys.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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 above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * 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 TUNGSTEN GRAPHICS 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.
- *
- **************************************************************************/
-
-
-#ifndef SW_WINSYS_H
-#define SW_WINSYS_H
-
-
-struct pipe_winsys;
-
-
-extern struct pipe_winsys *
-create_sw_winsys(void);
-
-
-#endif /* SW_WINSYS_H */
diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c
index 925f88a..9e3f82e 100644
--- a/src/gallium/winsys/g3dvl/xsp_winsys.c
+++ b/src/gallium/winsys/g3dvl/xsp_winsys.c
@@ -12,7 +12,7 @@
struct xsp_pipe_winsys
{
- struct pipe_winsys base;
+ struct softpipe_winsys base;
XImage fbimage;
};
@@ -24,74 +24,6 @@ struct xsp_context
int drawable_bound;
};
-struct xsp_buffer
-{
- struct softpipe_display_buffer base;
- void *data;
-};
-
-
-
-static void* xsp_buffer_map(struct softpipe_winsys *pws,
- struct softpipe_display_buffer *buffer)
-{
- struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
-
- assert(pws);
- assert(buffer);
-
- return xsp_buf->data;
-}
-
-static void xsp_buffer_unmap(struct softpipe_winsys *pws,
- struct softpipe_display_buffer *buffer)
-{
- assert(pws);
- assert(buffer);
-}
-
-static void xsp_buffer_destroy(struct softpipe_winsys *pws,
- struct softpipe_display_buffer *buffer)
-{
- struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
-
- assert(pws);
- assert(buffer);
-
- align_free(xsp_buf->data);
- free(xsp_buf);
-}
-
-static struct softpipe_display_buffer* xsp_display_buffer_create
-(
- struct softpipe_winsys *pws,
- unsigned width,
- unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride
-)
-{
- struct xsp_buffer *buffer;
- struct pipe_format_block block;
- unsigned nblocksx, nblocksy;
-
- assert(pws);
-
- pf_get_block(format, &block);
- nblocksx = pf_get_nblocksx(&block, width);
- nblocksy = pf_get_nblocksy(&block, height);
- *stride = align(nblocksx * block.size, ALIGNMENT);
-
- buffer = calloc(1, sizeof(struct xsp_buffer));
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.stride = *stride;
- buffer->base.size = size;
- buffer->data = align_malloc(size, alignment);
-
- return (struct softpipe_display_buffer*)buffer;
-}
static void xsp_flush_frontbuffer(struct pipe_winsys *pws,
@@ -134,10 +66,6 @@ static void xsp_flush_frontbuffer(struct pipe_winsys *pws,
XFlush(xsp_context->display);
}
-static void xsp_destroy(struct softpipe_winsys *pws)
-{
- free(pws);
-}
/* Show starts here */
@@ -168,20 +96,17 @@ int unbind_pipe_drawable(struct pipe_context *pipe)
struct pipe_context* create_pipe_context(Display *display, int screen)
{
- struct xsp_softpipe_winsys *xsp_winsys;
+ struct softpipe_winsys *xsp_winsys;
struct xsp_context *xsp_context;
struct pipe_screen *sp_screen;
struct pipe_context *sp_pipe;
assert(display);
- xsp_winsys = calloc(1, sizeof(struct xsp_pipe_winsys));
- xsp_winsys->base.display_buffer_create = xsp_buffer_create;
- xsp_winsys->base.display_buffer_map = xsp_buffer_map;
- xsp_winsys->base.display_buffer_unmap = xsp_buffer_unmap;
- xsp_winsys->base.display_buffer_destroy = xsp_buffer_destroy;
- xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer;
- xsp_winsys->base.destroy = xsp_destroy;
+ xsp_winsys =
+ (struct xpsb_winsys *)softpipe_create_malloc_winsys(
+ sizeof *xsp_winsys,
+ flush_frontbuffer );
{
/* XXX: Can't use the returned XImage* directly,
@@ -209,12 +134,13 @@ struct pipe_context* create_pipe_context(Display *display, int screen)
XDestroyImage(template);
}
- sp_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys);
+ sp_screen = softpipe_create_screen(&xsp_winsys->base);
sp_pipe = softpipe_create(sp_screen);
xsp_context = calloc(1, sizeof(struct xsp_context));
xsp_context->display = display;
xsp_context->screen = screen;
+ xsp_context->xsp_winsys = xsp_winsys;
sp_pipe->priv = xsp_context;
@@ -224,12 +150,10 @@ struct pipe_context* create_pipe_context(Display *display, int screen)
int destroy_pipe_context(struct pipe_context *pipe)
{
struct pipe_screen *screen;
- struct pipe_winsys *winsys;
assert(pipe);
screen = pipe->screen;
- winsys = pipe->winsys;
free(pipe->priv);
pipe->destroy(pipe);
screen->destroy(screen);
diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c
index c0286d6..621c606 100644
--- a/src/gallium/winsys/xlib/xlib_softpipe.c
+++ b/src/gallium/winsys/xlib/xlib_softpipe.c
@@ -66,7 +66,7 @@ struct xmesa_display_buffer
/**
- * Subclass of pipe_winsys for Xlib winsys
+ * Subclass of softpipe_winsys for Xlib winsys
*/
struct xmesa_softpipe_winsys
{
@@ -238,40 +238,22 @@ xm_buffer_destroy(struct softpipe_winsys *pws,
}
-/**
- * Display/copy the image in the surface into the X window specified
- * by the XMesaBuffer.
+/* Combined worker function for display_surface and flush_frontbuffer
+ * to really do the copy to the window:
*/
static void
-xlib_softpipe_display_surface(struct xmesa_buffer *b,
- struct pipe_surface *surf)
+do_present_buffer(struct xmesa_buffer *b,
+ struct softpipe_display_buffer *display_buffer )
{
XImage *ximage;
-
- struct softpipe_display_buffer *sp_disp =
- softpipe_surface_display_buffer(surf);
-
- struct xmesa_display_buffer *xm_buf =
- xmesa_display_buffer(sp_disp);
-
- static boolean no_swap = 0;
- static boolean firsttime = 1;
-
- if (firsttime) {
- no_swap = getenv("SP_NO_RAST") != NULL;
- firsttime = 0;
- }
-
- if (no_swap)
- return;
+ unsigned cpp = pf_get_size(display_buffer->format);
+ struct xmesa_display_buffer *xm_buf = xmesa_display_buffer(display_buffer);
#ifdef USE_XSHM
if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) {
- assert(surf->texture->block.width == 1);
- assert(surf->texture->block.height == 1);
alloc_shm_ximage(xm_buf, b,
- sp_disp->stride / surf->texture->block.size,
- surf->height);
+ display_buffer->stride / cpp,
+ display_buffer->height);
}
#endif
@@ -282,7 +264,9 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b,
#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);
+ ximage, 0, 0, 0, 0,
+ display_buffer->width,
+ display_buffer->height, False);
} else
#endif
{
@@ -291,19 +275,56 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b,
assert(ximage->bitmap_unit);
/* update XImage's fields */
- ximage->width = surf->width;
- ximage->height = surf->height;
- ximage->bytes_per_line = sp_disp->stride;
+ ximage->width = display_buffer->width;
+ ximage->height = display_buffer->height;
+ ximage->bytes_per_line = display_buffer->stride;
XPutImage(b->xm_visual->display, b->drawable, b->gc,
- ximage, 0, 0, 0, 0, surf->width, surf->height);
+ ximage, 0, 0, 0, 0,
+ display_buffer->width,
+ display_buffer->height);
}
}
+
+/**
+ * Request from GLX/xlib to display/copy the image in the surface into
+ * the X window specified by the XMesaBuffer.
+ *
+ * This effectively implements glXSwapBuffers in double-buffered windows.
+ */
+static void
+xlib_softpipe_display_surface(struct xmesa_buffer *b,
+ struct pipe_surface *surf)
+{
+ struct softpipe_display_buffer *sp_disp =
+ softpipe_surface_display_buffer(surf);
+
+ static boolean no_swap = 0;
+ static boolean firsttime = 1;
+
+ if (firsttime) {
+ no_swap = getenv("SP_NO_RAST") != NULL;
+ firsttime = 0;
+ }
+
+ if (no_swap)
+ return;
+
+ if (sp_disp)
+ do_present_buffer(b, sp_disp);
+}
+
+
+/* Request from mesa state tracker through softpipe to figure out the
+ * window associated withe a display target and copy the image there.
+ *
+ * This effectively implements GLFlush() for single-buffered windows.
+ */
static void
xm_flush_frontbuffer(struct softpipe_winsys *pws,
- struct pipe_surface *surf,
+ struct softpipe_display_buffer *display_buffer,
void *context_private)
{
/*
@@ -311,7 +332,7 @@ xm_flush_frontbuffer(struct softpipe_winsys *pws,
* This function copies that XImage to the actual X Window.
*/
XMesaContext xmctx = (XMesaContext) context_private;
- xlib_softpipe_display_surface(xmctx->xm_buffer, surf);
+ do_present_buffer(xmctx->xm_buffer, display_buffer);
}
@@ -340,7 +361,10 @@ xm_display_buffer_create(struct softpipe_winsys *winsys,
buffer->base.stride = *stride;
buffer->base.size = *stride * height;
-
+ buffer->base.width = width;
+ buffer->base.height = height;
+ buffer->base.format = format;
+
#ifdef USE_XSHM
buffer->shminfo.shmid = -1;
buffer->shminfo.shmaddr = (char *) -1;
More information about the mesa-commit
mailing list