summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorJakob Bornecrantz <jakob@vmware.com>2010-03-11 03:33:03 +0000
committerJakob Bornecrantz <jakob@vmware.com>2010-03-16 01:06:46 +0000
commit8b63f9b497c22cb59678588d921699189f8b712f (patch)
tree35f96ec3a95cada800a834e25db0a7c1effbf592 /src/gallium
parenteaee22ac880e431028ac4c6854af1873d5765869 (diff)
winsys/sw: Add a software winsys layered on a pipe
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c6
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c51
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c54
-rw-r--r--src/gallium/include/state_tracker/sw_winsys.h20
-rw-r--r--src/gallium/winsys/drm/Makefile2
-rw-r--r--src/gallium/winsys/drm/i965/dri/Makefile1
-rw-r--r--src/gallium/winsys/drm/i965/gem/i965_drm_api.c12
-rw-r--r--src/gallium/winsys/drm/sw/Makefile14
-rw-r--r--src/gallium/winsys/drm/sw/sw_drm_api.c97
-rw-r--r--src/gallium/winsys/drm/sw/sw_drm_api.h34
-rw-r--r--src/gallium/winsys/drm/sw/wrapper_sw_winsys.c282
-rw-r--r--src/gallium/winsys/drm/sw/wrapper_sw_winsys.h35
-rw-r--r--src/gallium/winsys/gdi/gdi_sw_winsys.c25
-rw-r--r--src/gallium/winsys/null/null_sw_winsys.c24
-rw-r--r--src/gallium/winsys/xlib/xlib_sw_winsys.c25
18 files changed, 685 insertions, 10 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index 31fd963d19..f5528a7ec6 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -142,8 +142,10 @@ cell_is_format_supported( struct pipe_screen *screen,
format == PIPE_FORMAT_A8B8G8R8_SRGB)
return FALSE;
- if (tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
- if (!winsys->is_displaytarget_format_supported(winsys, format))
+ if (tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
+ if (!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
return FALSE;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index c65c3b4f88..5b169afaf8 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -105,6 +105,7 @@ cell_displaytarget_layout(struct pipe_screen *screen,
/* Round up the surface size to a multiple of the tile size?
*/
ct->dt = winsys->displaytarget_create(winsys,
+ ct->base->tex_usage,
ct->base.format,
ct->base.width0,
ct->base.height0,
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 5093f58bb1..f1bbc2092c 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -204,8 +204,10 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
return FALSE;
}
- if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
- if(!winsys->is_displaytarget_format_supported(winsys, format))
+ if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
+ if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
return FALSE;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 9a85a42897..10ede9bb04 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -103,6 +103,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
unsigned height = align(lpt->base.height0, TILE_SIZE);
lpt->dt = winsys->displaytarget_create(winsys,
+ lpt->base.tex_usage,
lpt->base.format,
width, height,
16,
@@ -250,6 +251,55 @@ llvmpipe_texture_unmap(struct pipe_texture *texture,
}
+static struct pipe_texture *
+llvmpipe_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_texture *template,
+ struct winsys_handle *whandle)
+{
+ struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
+ struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture);
+ if (!lpt)
+ return NULL;
+
+ lpt->base = *template;
+ pipe_reference_init(&lpt->base.reference, 1);
+ lpt->base.screen = screen;
+
+ lpt->pot = (util_is_power_of_two(template->width0) &&
+ util_is_power_of_two(template->height0) &&
+ util_is_power_of_two(template->depth0));
+
+ lpt->dt = winsys->displaytarget_from_handle(winsys,
+ template,
+ whandle,
+ &lpt->stride[0]);
+ if (!lpt->dt)
+ goto fail;
+
+ return &lpt->base;
+
+ fail:
+ FREE(lpt);
+ return NULL;
+}
+
+
+static boolean
+llvmpipe_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ struct winsys_handle *whandle)
+{
+ struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
+ struct llvmpipe_texture *lpt = llvmpipe_texture(pt);
+
+ assert(lpt->dt);
+ if (!lpt->dt)
+ return FALSE;
+
+ return winsys->displaytarget_get_handle(winsys, lpt->dt, whandle);
+}
+
+
static struct pipe_surface *
llvmpipe_get_tex_surface(struct pipe_screen *screen,
struct pipe_texture *pt,
@@ -418,6 +468,7 @@ llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = llvmpipe_texture_create;
screen->texture_destroy = llvmpipe_texture_destroy;
+ screen->texture_get_handle = llvmpipe_texture_get_handle;
screen->get_tex_surface = llvmpipe_get_tex_surface;
screen->tex_surface_destroy = llvmpipe_tex_surface_destroy;
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index d62bfa3d63..757dc86128 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -173,8 +173,10 @@ softpipe_is_format_supported( struct pipe_screen *screen,
break;
}
- if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
- if(!winsys->is_displaytarget_format_supported(winsys, format))
+ if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
+ if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
return FALSE;
}
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 2aff6118f4..f4983b7c8e 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -91,6 +91,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen,
/* Round up the surface size to a multiple of the tile size?
*/
spt->dt = winsys->displaytarget_create(winsys,
+ spt->base.tex_usage,
spt->base.format,
spt->base.width0,
spt->base.height0,
@@ -139,8 +140,6 @@ softpipe_texture_create(struct pipe_screen *screen,
}
-
-
static void
softpipe_texture_destroy(struct pipe_texture *pt)
{
@@ -161,6 +160,55 @@ softpipe_texture_destroy(struct pipe_texture *pt)
}
+static struct pipe_texture *
+softpipe_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_texture *template,
+ struct winsys_handle *whandle)
+{
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+ struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
+ if (!spt)
+ return NULL;
+
+ spt->base = *template;
+ pipe_reference_init(&spt->base.reference, 1);
+ spt->base.screen = screen;
+
+ spt->pot = (util_is_power_of_two(template->width0) &&
+ util_is_power_of_two(template->height0) &&
+ util_is_power_of_two(template->depth0));
+
+ spt->dt = winsys->displaytarget_from_handle(winsys,
+ template,
+ whandle,
+ &spt->stride[0]);
+ if (!spt->dt)
+ goto fail;
+
+ return &spt->base;
+
+ fail:
+ FREE(spt);
+ return NULL;
+}
+
+
+static boolean
+softpipe_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ struct winsys_handle *whandle)
+{
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+ struct softpipe_texture *spt = softpipe_texture(pt);
+
+ assert(spt->dt);
+ if (!spt->dt)
+ return FALSE;
+
+ return winsys->displaytarget_get_handle(winsys, spt->dt, whandle);
+}
+
+
/**
* Get a pipe_surface "view" into a texture.
*/
@@ -461,6 +509,8 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = softpipe_texture_create;
screen->texture_destroy = softpipe_texture_destroy;
+ screen->texture_from_handle = softpipe_texture_from_handle;
+ screen->texture_get_handle = softpipe_texture_get_handle;
screen->get_tex_surface = softpipe_get_tex_surface;
screen->tex_surface_destroy = softpipe_tex_surface_destroy;
diff --git a/src/gallium/include/state_tracker/sw_winsys.h b/src/gallium/include/state_tracker/sw_winsys.h
index 0de98bbc1c..9d202e48bf 100644
--- a/src/gallium/include/state_tracker/sw_winsys.h
+++ b/src/gallium/include/state_tracker/sw_winsys.h
@@ -44,6 +44,7 @@ extern "C" {
#endif
+struct winsys_handle;
struct pipe_screen;
struct pipe_context;
@@ -68,6 +69,7 @@ struct sw_winsys
boolean
(*is_displaytarget_format_supported)( struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format );
/**
@@ -83,12 +85,30 @@ struct sw_winsys
*/
struct sw_displaytarget *
(*displaytarget_create)( struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
unsigned *stride );
/**
+ * Used to implement texture_from_handle.
+ */
+ struct sw_displaytarget *
+ (*displaytarget_from_handle)( struct sw_winsys *ws,
+ const struct pipe_texture *templat,
+ struct winsys_handle *whandle,
+ unsigned *stride );
+
+ /**
+ * Used to implement texture_get_handle.
+ */
+ boolean
+ (*displaytarget_get_handle)( struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle );
+
+ /**
* \param flags bitmask of PIPE_BUFFER_USAGE_x flags
*/
void *
diff --git a/src/gallium/winsys/drm/Makefile b/src/gallium/winsys/drm/Makefile
index fee0191643..a998aff931 100644
--- a/src/gallium/winsys/drm/Makefile
+++ b/src/gallium/winsys/drm/Makefile
@@ -2,7 +2,7 @@
TOP = ../../../..
include $(TOP)/configs/current
-SUBDIRS = $(GALLIUM_WINSYS_DRM_DIRS)
+SUBDIRS = sw $(GALLIUM_WINSYS_DRM_DIRS)
default install clean:
@for dir in $(SUBDIRS) ; do \
diff --git a/src/gallium/winsys/drm/i965/dri/Makefile b/src/gallium/winsys/drm/i965/dri/Makefile
index f7e81eed87..56690769fc 100644
--- a/src/gallium/winsys/drm/i965/dri/Makefile
+++ b/src/gallium/winsys/drm/i965/dri/Makefile
@@ -7,6 +7,7 @@ PIPE_DRIVERS = \
$(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
$(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/winsys/drm/sw/libswdrm.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/identity/libidentity.a \
$(TOP)/src/gallium/drivers/i965/libi965.a
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_api.c b/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
index 21e82303f7..2ebc05f47e 100644
--- a/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
+++ b/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
@@ -10,6 +10,8 @@
#include "trace/tr_drm.h"
+#include "../../sw/sw_drm_api.h"
+
/*
* Helper functions
*/
@@ -108,5 +110,13 @@ struct drm_api i965_libdrm_api =
struct drm_api *
drm_api_create()
{
- return trace_drm_create(&i965_libdrm_api);
+ struct drm_api *api;
+
+ if (api == NULL && debug_get_bool_option("BRW_SOFTPIPE", FALSE))
+ api = sw_drm_api_create(&i965_libdrm_api);
+
+ if (api == NULL)
+ api = &i965_libdrm_api;
+
+ return trace_drm_create(api);
}
diff --git a/src/gallium/winsys/drm/sw/Makefile b/src/gallium/winsys/drm/sw/Makefile
new file mode 100644
index 0000000000..5f3c3ec325
--- /dev/null
+++ b/src/gallium/winsys/drm/sw/Makefile
@@ -0,0 +1,14 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = swdrm
+
+C_SOURCES = \
+ wrapper_sw_winsys.c \
+ sw_drm_api.c
+
+LIBRARY_INCLUDES =
+
+LIBRARY_DEFINES =
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/drm/sw/sw_drm_api.c b/src/gallium/winsys/drm/sw/sw_drm_api.c
new file mode 100644
index 0000000000..0fd2163913
--- /dev/null
+++ b/src/gallium/winsys/drm/sw/sw_drm_api.c
@@ -0,0 +1,97 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+
+#include "util/u_memory.h"
+#include "softpipe/sp_public.h"
+#include "state_tracker/drm_api.h"
+#include "wrapper_sw_winsys.h"
+#include "sw_drm_api.h"
+
+
+/*
+ * Defines
+ */
+
+
+struct sw_drm_api
+{
+ struct drm_api base;
+ struct drm_api *api;
+ struct sw_winsys *sw;
+};
+
+static INLINE struct sw_drm_api *
+sw_drm_api(struct drm_api *api)
+{
+ return (struct sw_drm_api *)api;
+}
+
+
+/*
+ * Exported functions
+ */
+
+
+static struct pipe_screen *
+sw_drm_create_screen(struct drm_api *_api, int drmFD,
+ struct drm_create_screen_arg *arg)
+{
+ struct sw_drm_api *swapi = sw_drm_api(_api);
+ struct drm_api *api = swapi->api;
+ struct sw_winsys *sww;
+ struct pipe_screen *screen;
+
+ screen = api->create_screen(api, drmFD, arg);
+
+ sww = wrapper_sw_winsys_warp_pipe_screen(screen);
+
+ return softpipe_create_screen(sww);
+}
+
+static void
+sw_drm_destroy(struct drm_api *api)
+{
+ struct sw_drm_api *swapi = sw_drm_api(api);
+ if (swapi->api->destroy)
+ swapi->api->destroy(swapi->api);
+
+ FREE(swapi);
+}
+
+struct drm_api *
+sw_drm_api_create(struct drm_api *api)
+{
+ struct sw_drm_api *swapi = CALLOC_STRUCT(sw_drm_api);
+
+ swapi->base.name = "sw";
+ swapi->base.driver_name = api->driver_name;
+ swapi->base.create_screen = sw_drm_create_screen;
+ swapi->base.destroy = sw_drm_destroy;
+
+ swapi->api = api;
+
+ return &swapi->base;
+}
diff --git a/src/gallium/winsys/drm/sw/sw_drm_api.h b/src/gallium/winsys/drm/sw/sw_drm_api.h
new file mode 100644
index 0000000000..ce90a04ae0
--- /dev/null
+++ b/src/gallium/winsys/drm/sw/sw_drm_api.h
@@ -0,0 +1,34 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_DRM_API_H
+#define SW_DRM_API_H
+
+struct drm_api;
+
+struct drm_api * sw_drm_api_create(struct drm_api *api);
+
+#endif
diff --git a/src/gallium/winsys/drm/sw/wrapper_sw_winsys.c b/src/gallium/winsys/drm/sw/wrapper_sw_winsys.c
new file mode 100644
index 0000000000..459b1c1e2a
--- /dev/null
+++ b/src/gallium/winsys/drm/sw/wrapper_sw_winsys.c
@@ -0,0 +1,282 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+
+#include "wrapper_sw_winsys.h"
+
+#include "pipe/p_format.h"
+#include "pipe/p_state.h"
+
+#include "state_tracker/sw_winsys.h"
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+/*
+ * This code wraps a pipe_screen and exposes a sw_winsys interface for use
+ * with software resterizers. This code is used by the DRM based winsys to
+ * allow access to the drm driver.
+ *
+ * We must borrow the whole stack because only the pipe screen knows how
+ * to decode the content of a buffer. Or how to create a buffer that
+ * can still be used by drivers using real hardware (as the case is
+ * with software st/xorg but hw st/dri).
+ *
+ * We also need a pipe context for the transfers.
+ */
+
+struct wrapper_sw_winsys
+{
+ struct sw_winsys base;
+ struct pipe_screen *screen;
+ struct pipe_context *pipe;
+};
+
+struct wrapper_sw_displaytarget
+{
+ struct wrapper_sw_winsys *winsys;
+ struct pipe_texture *tex;
+ struct pipe_transfer *transfer;
+
+ unsigned width;
+ unsigned height;
+ unsigned map_count;
+ unsigned stride; /**< because we give stride at create */
+ void *ptr;
+};
+
+static INLINE struct wrapper_sw_winsys *
+wrapper_sw_winsys(struct sw_winsys *ws)
+{
+ return (struct wrapper_sw_winsys *)ws;
+}
+
+static INLINE struct wrapper_sw_displaytarget *
+wrapper_sw_displaytarget(struct sw_displaytarget *dt)
+{
+ return (struct wrapper_sw_displaytarget *)dt;
+}
+
+
+/*
+ * Functions
+ */
+
+
+static boolean
+wsw_dt_get_stride(struct wrapper_sw_displaytarget *wdt, unsigned *stride)
+{
+ struct pipe_context *pipe = wdt->winsys->pipe;
+ struct pipe_texture *tex = wdt->tex;
+ struct pipe_transfer *tr;
+
+ tr = pipe->get_tex_transfer(pipe, tex, 0, 0, 0,
+ PIPE_TRANSFER_READ_WRITE,
+ 0, 0, wdt->width, wdt->height);
+ if (!tr)
+ return FALSE;
+
+ *stride = tr->stride;
+ wdt->stride = tr->stride;
+
+ pipe->tex_transfer_destroy(pipe, tr);
+
+ return TRUE;
+}
+
+static struct sw_displaytarget *
+wsw_dt_wrap_texture(struct wrapper_sw_winsys *wsw,
+ struct pipe_texture *tex, unsigned *stride)
+{
+ struct wrapper_sw_displaytarget *wdt = CALLOC_STRUCT(wrapper_sw_displaytarget);
+ if (!wdt)
+ goto err_unref;
+
+ wdt->tex = tex;
+ wdt->winsys = wsw;
+
+ if (!wsw_dt_get_stride(wdt, stride))
+ goto err_free;
+
+ return (struct sw_displaytarget *)wdt;
+
+err_free:
+ FREE(wdt);
+err_unref:
+ pipe_texture_reference(&tex, NULL);
+ return NULL;
+}
+
+static struct sw_displaytarget *
+wsw_dt_create(struct sw_winsys *ws,
+ unsigned tex_usage,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+ struct pipe_texture templ;
+ struct pipe_texture *tex;
+
+ /*
+ * XXX Why don't we just get the template.
+ */
+ memset(&templ, 0, sizeof(templ));
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.format = format;
+ templ.tex_usage = tex_usage;
+
+ /* XXX alignment: we can't do anything about this */
+
+ tex = wsw->screen->texture_create(wsw->screen, &templ);
+ if (!tex)
+ return NULL;
+
+ return wsw_dt_wrap_texture(wsw, tex, stride);
+}
+
+static struct sw_displaytarget *
+wsw_dt_from_handle(struct sw_winsys *ws,
+ const struct pipe_texture *templ,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+ struct pipe_texture *tex;
+
+ tex = wsw->screen->texture_from_handle(wsw->screen, templ, whandle);
+ if (!tex)
+ return NULL;
+
+ return wsw_dt_wrap_texture(wsw, tex, stride);
+}
+
+static void *
+wsw_dt_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags)
+{
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+ struct pipe_context *pipe = wdt->winsys->pipe;
+ struct pipe_texture *tex = wdt->tex;
+ struct pipe_transfer *tr;
+ void *ptr;
+
+ if (!wdt->map_count) {
+
+ assert(!wdt->transfer);
+
+ tr = pipe->get_tex_transfer(pipe, tex, 0, 0, 0,
+ PIPE_TRANSFER_READ_WRITE,
+ 0, 0, wdt->width, wdt->height);
+ if (!tr)
+ return NULL;
+
+ ptr = pipe->transfer_map(pipe, tr);
+ if (!ptr)
+ goto err;
+
+ wdt->transfer = tr;
+ wdt->ptr = ptr;
+
+ /* XXX Handle this case */
+ assert(tr->stride == wdt->stride);
+ }
+
+ wdt->map_count++;
+
+ return wdt->ptr;
+
+err:
+ pipe->tex_transfer_destroy(pipe, tr);
+ return NULL;
+}
+
+static void
+wsw_dt_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+ struct pipe_context *pipe = wdt->winsys->pipe;
+
+ assert(wdt->transfer);
+
+ wdt->map_count--;
+
+ if (wdt->map_count)
+ return;
+
+ pipe->transfer_unmap(pipe, wdt->transfer);
+ pipe->tex_transfer_destroy(pipe, wdt->transfer);
+ wdt->transfer = NULL;
+}
+
+static void
+wsw_dt_destroy(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+
+ pipe_texture_reference(&wdt->tex, NULL);
+
+ FREE(wdt);
+}
+
+static void
+wsw_destroy(struct sw_winsys *ws)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+
+ wsw->pipe->destroy(wsw->pipe);
+ wsw->screen->destroy(wsw->screen);
+
+ FREE(wsw);
+}
+
+struct sw_winsys *
+wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen)
+{
+ struct wrapper_sw_winsys *wsw = CALLOC_STRUCT(wrapper_sw_winsys);
+
+ wsw->base.displaytarget_create = wsw_dt_create;
+ wsw->base.displaytarget_from_handle = wsw_dt_from_handle;
+ wsw->base.displaytarget_map = wsw_dt_map;
+ wsw->base.displaytarget_unmap = wsw_dt_unmap;
+ wsw->base.displaytarget_destroy = wsw_dt_destroy;
+ wsw->base.destroy = wsw_destroy;
+
+ wsw->screen = screen;
+ wsw->pipe = screen->context_create(screen, NULL);
+ if (!wsw->pipe)
+ goto err;
+
+ return &wsw->base;
+
+err:
+ FREE(wsw);
+ return NULL;
+}
diff --git a/src/gallium/winsys/drm/sw/wrapper_sw_winsys.h b/src/gallium/winsys/drm/sw/wrapper_sw_winsys.h
new file mode 100644
index 0000000000..b5c25a3c50
--- /dev/null
+++ b/src/gallium/winsys/drm/sw/wrapper_sw_winsys.h
@@ -0,0 +1,35 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 WRAPPER_SW_WINSYS
+#define WRAPPER_SW_WINSYS
+
+struct sw_winsys;
+struct pipe_screen;
+
+struct sw_winsys *wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen);
+
+#endif
diff --git a/src/gallium/winsys/gdi/gdi_sw_winsys.c b/src/gallium/winsys/gdi/gdi_sw_winsys.c
index f5c0b7d56e..4dba4b577b 100644
--- a/src/gallium/winsys/gdi/gdi_sw_winsys.c
+++ b/src/gallium/winsys/gdi/gdi_sw_winsys.c
@@ -71,6 +71,7 @@ gdi_sw_displaytarget( struct sw_displaytarget *buf )
static boolean
gdi_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format )
{
switch(format) {
@@ -119,6 +120,7 @@ gdi_sw_displaytarget_destroy(struct sw_winsys *winsys,
static struct sw_displaytarget *
gdi_sw_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
@@ -168,6 +170,27 @@ no_gdt:
}
+static struct sw_displaytarget *
+gdi_sw_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_texture *templet,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ assert(0);
+ return NULL;
+}
+
+
+static boolean
+gdi_sw_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+
void
gdi_sw_display( struct sw_winsys *winsys,
struct sw_displaytarget *dt,
@@ -212,6 +235,8 @@ gdi_create_sw_winsys(void)
winsys->destroy = gdi_sw_destroy;
winsys->is_displaytarget_format_supported = gdi_sw_is_displaytarget_format_supported;
winsys->displaytarget_create = gdi_sw_displaytarget_create;
+ winsys->displaytarget_from_handle = gdi_sw_displaytarget_from_handle;
+ winsys->displaytarget_get_handle = gdi_sw_displaytarget_get_handle;
winsys->displaytarget_map = gdi_sw_displaytarget_map;
winsys->displaytarget_unmap = gdi_sw_displaytarget_unmap;
winsys->displaytarget_display = gdi_sw_displaytarget_display;
diff --git a/src/gallium/winsys/null/null_sw_winsys.c b/src/gallium/winsys/null/null_sw_winsys.c
index d961d34860..5027e57b30 100644
--- a/src/gallium/winsys/null/null_sw_winsys.c
+++ b/src/gallium/winsys/null/null_sw_winsys.c
@@ -44,6 +44,7 @@
static boolean
null_sw_is_displaytarget_format_supported(struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format )
{
return FALSE;
@@ -78,6 +79,7 @@ null_sw_displaytarget_destroy(struct sw_winsys *winsys,
static struct sw_displaytarget *
null_sw_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
@@ -87,6 +89,26 @@ null_sw_displaytarget_create(struct sw_winsys *winsys,
}
+static struct sw_displaytarget *
+null_sw_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_texture *templet,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ return NULL;
+}
+
+
+static boolean
+null_sw_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+
static void
null_sw_displaytarget_display(struct sw_winsys *winsys,
struct sw_displaytarget *dt,
@@ -115,6 +137,8 @@ null_sw_create(void)
winsys->destroy = null_sw_destroy;
winsys->is_displaytarget_format_supported = null_sw_is_displaytarget_format_supported;
winsys->displaytarget_create = null_sw_displaytarget_create;
+ winsys->displaytarget_from_handle = null_sw_displaytarget_from_handle;
+ winsys->displaytarget_get_handle = null_sw_displaytarget_get_handle;
winsys->displaytarget_map = null_sw_displaytarget_map;
winsys->displaytarget_unmap = null_sw_displaytarget_unmap;
winsys->displaytarget_display = null_sw_displaytarget_display;
diff --git a/src/gallium/winsys/xlib/xlib_sw_winsys.c b/src/gallium/winsys/xlib/xlib_sw_winsys.c
index cecfa4a53d..54789d7a87 100644
--- a/src/gallium/winsys/xlib/xlib_sw_winsys.c
+++ b/src/gallium/winsys/xlib/xlib_sw_winsys.c
@@ -208,6 +208,7 @@ alloc_ximage(struct xm_displaytarget *xm_dt,
static boolean
xm_is_displaytarget_format_supported( struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format )
{
/* TODO: check visuals or other sensible thing here */
@@ -358,6 +359,7 @@ xm_displaytarget_display(struct sw_winsys *ws,
static struct sw_displaytarget *
xm_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
@@ -406,6 +408,27 @@ no_xm_dt:
}
+static struct sw_displaytarget *
+xm_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_texture *templet,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ assert(0);
+ return NULL;
+}
+
+
+static boolean
+xm_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+
static void
xm_destroy( struct sw_winsys *ws )
{
@@ -428,6 +451,8 @@ xlib_create_sw_winsys( Display *display )
ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
ws->base.displaytarget_create = xm_displaytarget_create;
+ ws->base.displaytarget_from_handle = xm_displaytarget_from_handle;
+ ws->base.displaytarget_get_handle = xm_displaytarget_get_handle;
ws->base.displaytarget_map = xm_displaytarget_map;
ws->base.displaytarget_unmap = xm_displaytarget_unmap;
ws->base.displaytarget_destroy = xm_displaytarget_destroy;