winsys/sw: Add a software winsys layered on a pipe
authorJakob Bornecrantz <jakob@vmware.com>
Thu, 11 Mar 2010 03:33:03 +0000 (03:33 +0000)
committerJakob Bornecrantz <jakob@vmware.com>
Tue, 16 Mar 2010 01:06:46 +0000 (01:06 +0000)
18 files changed:
src/gallium/drivers/cell/ppu/cell_screen.c
src/gallium/drivers/cell/ppu/cell_texture.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/llvmpipe/lp_texture.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/softpipe/sp_texture.c
src/gallium/include/state_tracker/sw_winsys.h
src/gallium/winsys/drm/Makefile
src/gallium/winsys/drm/i965/dri/Makefile
src/gallium/winsys/drm/i965/gem/i965_drm_api.c
src/gallium/winsys/drm/sw/Makefile [new file with mode: 0644]
src/gallium/winsys/drm/sw/sw_drm_api.c [new file with mode: 0644]
src/gallium/winsys/drm/sw/sw_drm_api.h [new file with mode: 0644]
src/gallium/winsys/drm/sw/wrapper_sw_winsys.c [new file with mode: 0644]
src/gallium/winsys/drm/sw/wrapper_sw_winsys.h [new file with mode: 0644]
src/gallium/winsys/gdi/gdi_sw_winsys.c
src/gallium/winsys/null/null_sw_winsys.c
src/gallium/winsys/xlib/xlib_sw_winsys.c

index 31fd963..f5528a7 100644 (file)
@@ -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;
    }
 
index c65c3b4..5b169af 100644 (file)
@@ -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,
index 5093f58..f1bbc20 100644 (file)
@@ -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;
    }
 
index 9a85a42..10ede9b 100644 (file)
@@ -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;
index d62bfa3..757dc86 100644 (file)
@@ -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;
    }
 
index 2aff611..f4983b7 100644 (file)
@@ -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;
index 0de98bb..9d202e4 100644 (file)
@@ -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 *
index fee0191..a998aff 100644 (file)
@@ -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 \
index f7e81ee..5669076 100644 (file)
@@ -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
index 21e8230..2ebc05f 100644 (file)
@@ -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 (file)
index 0000000..5f3c3ec
--- /dev/null
@@ -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 (file)
index 0000000..0fd2163
--- /dev/null
@@ -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 (file)
index 0000000..ce90a04
--- /dev/null
@@ -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 (file)
index 0000000..459b1c1
--- /dev/null
@@ -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 (file)
index 0000000..b5c25a3
--- /dev/null
@@ -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
index f5c0b7d..4dba4b5 100644 (file)
@@ -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;
index d961d34..5027e57 100644 (file)
@@ -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;
index cecfa4a..54789d7 100644 (file)
@@ -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;