diff options
Diffstat (limited to 'src/gallium/winsys/sw')
27 files changed, 2171 insertions, 0 deletions
| diff --git a/src/gallium/winsys/sw/Makefile b/src/gallium/winsys/sw/Makefile new file mode 100644 index 0000000000..e9182ea5b1 --- /dev/null +++ b/src/gallium/winsys/sw/Makefile @@ -0,0 +1,12 @@ +# src/gallium/winsys/sw/Makefile +TOP = ../../../.. +include $(TOP)/configs/current + +SUBDIRS = null wrapper + +default install clean: +	@for dir in $(SUBDIRS) ; do \ +		if [ -d $$dir ] ; then \ +			(cd $$dir && $(MAKE) $@) || exit 1; \ +		fi \ +	done diff --git a/src/gallium/winsys/sw/dri/Makefile b/src/gallium/winsys/sw/dri/Makefile new file mode 100644 index 0000000000..a3fca6be88 --- /dev/null +++ b/src/gallium/winsys/sw/dri/Makefile @@ -0,0 +1,13 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = swdri + +LIBRARY_INCLUDES = + +LIBRARY_DEFINES = + +C_SOURCES = \ +	dri_sw_winsys.c + +include ../../../Makefile.template diff --git a/src/gallium/winsys/sw/dri/SConscript b/src/gallium/winsys/sw/dri/SConscript new file mode 100644 index 0000000000..b255d725f9 --- /dev/null +++ b/src/gallium/winsys/sw/dri/SConscript @@ -0,0 +1,23 @@ +####################################################################### +# SConscript for xlib winsys + + +Import('*') + +if env['platform'] == 'linux': + +    env = env.Clone() + +    env.Append(CPPPATH = [ +        '#/src/gallium/include', +        '#/src/gallium/auxiliary', +        '#/src/gallium/drivers', +    ]) + +    ws_dri = env.ConvenienceLibrary( +        target = 'ws_dri', +        source = [ +           'dri_sw_winsys.c', +        ] +    ) +    Export('ws_dri') diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c new file mode 100644 index 0000000000..1bca827bd6 --- /dev/null +++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c @@ -0,0 +1,225 @@ +/************************************************************************** + * + * Copyright 2009, VMware, Inc. + * All Rights Reserved. + * Copyright 2010 George Sapountzis <gsapountzis@gmail.com> + * + * 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 VMWARE 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. + * + **************************************************************************/ + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "state_tracker/sw_winsys.h" +#include "dri_sw_winsys.h" + + +struct dri_sw_displaytarget +{ +   enum pipe_format format; +   unsigned width; +   unsigned height; +   unsigned stride; + +   void *data; +   void *mapped; +}; + +struct dri_sw_winsys +{ +   struct sw_winsys base; + +   struct drisw_loader_funcs *lf; +}; + +static INLINE struct dri_sw_displaytarget * +dri_sw_displaytarget( struct sw_displaytarget *dt ) +{ +   return (struct dri_sw_displaytarget *)dt; +} + +static INLINE struct dri_sw_winsys * +dri_sw_winsys( struct sw_winsys *ws ) +{ +   return (struct dri_sw_winsys *)ws; +} + + +static boolean +dri_sw_is_displaytarget_format_supported( struct sw_winsys *ws, +                                          unsigned tex_usage, +                                          enum pipe_format format ) +{ +   /* TODO: check visuals or other sensible thing here */ +   return TRUE; +} + +static struct sw_displaytarget * +dri_sw_displaytarget_create(struct sw_winsys *winsys, +                            unsigned tex_usage, +                            enum pipe_format format, +                            unsigned width, unsigned height, +                            unsigned alignment, +                            unsigned *stride) +{ +   struct dri_sw_displaytarget *dri_sw_dt; +   unsigned nblocksy, size, format_stride; + +   dri_sw_dt = CALLOC_STRUCT(dri_sw_displaytarget); +   if(!dri_sw_dt) +      goto no_dt; + +   dri_sw_dt->format = format; +   dri_sw_dt->width = width; +   dri_sw_dt->height = height; + +   format_stride = util_format_get_stride(format, width); +   dri_sw_dt->stride = align(format_stride, alignment); + +   nblocksy = util_format_get_nblocksy(format, height); +   size = dri_sw_dt->stride * nblocksy; + +   dri_sw_dt->data = align_malloc(size, alignment); +   if(!dri_sw_dt->data) +      goto no_data; + +   *stride = dri_sw_dt->stride; +   return (struct sw_displaytarget *)dri_sw_dt; + +no_data: +   FREE(dri_sw_dt); +no_dt: +   return NULL; +} + +static void +dri_sw_displaytarget_destroy(struct sw_winsys *ws, +                             struct sw_displaytarget *dt) +{ +   struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt); + +   if (dri_sw_dt->data) { +      FREE(dri_sw_dt->data); +   } + +   FREE(dri_sw_dt); +} + +static void * +dri_sw_displaytarget_map(struct sw_winsys *ws, +                         struct sw_displaytarget *dt, +                         unsigned flags) +{ +   struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt); +   dri_sw_dt->mapped = dri_sw_dt->data; +   return dri_sw_dt->mapped; +} + +static void +dri_sw_displaytarget_unmap(struct sw_winsys *ws, +                           struct sw_displaytarget *dt) +{ +   struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt); +   dri_sw_dt->mapped = NULL; +} + +static struct sw_displaytarget * +dri_sw_displaytarget_from_handle(struct sw_winsys *winsys, +                                 const struct pipe_resource *templ, +                                 struct winsys_handle *whandle, +                                 unsigned *stride) +{ +   assert(0); +   return NULL; +} + +static boolean +dri_sw_displaytarget_get_handle(struct sw_winsys *winsys, +                                struct sw_displaytarget *dt, +                                struct winsys_handle *whandle) +{ +   assert(0); +   return FALSE; +} + +static void +dri_sw_displaytarget_display(struct sw_winsys *ws, +                             struct sw_displaytarget *dt, +                             void *context_private) +{ +   struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws); +   struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt); +   struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private; +   unsigned width, height; + +   /* Set the width to 'stride / cpp'. +    * +    * PutImage correctly clips to the width of the dst drawable. +    */ +   width = dri_sw_dt->stride / util_format_get_blocksize(dri_sw_dt->format); + +   height = dri_sw_dt->height; + +   dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height); +} + + +static void +dri_destroy_sw_winsys(struct sw_winsys *winsys) +{ +   FREE(winsys); +} + +struct sw_winsys * +dri_create_sw_winsys(struct drisw_loader_funcs *lf) +{ +   struct dri_sw_winsys *ws; + +   ws = CALLOC_STRUCT(dri_sw_winsys); +   if (!ws) +      return NULL; + +   ws->lf = lf; +   ws->base.destroy = dri_destroy_sw_winsys; + +   ws->base.is_displaytarget_format_supported = dri_sw_is_displaytarget_format_supported; + +   /* screen texture functions */ +   ws->base.displaytarget_create = dri_sw_displaytarget_create; +   ws->base.displaytarget_destroy = dri_sw_displaytarget_destroy; +   ws->base.displaytarget_from_handle = dri_sw_displaytarget_from_handle; +   ws->base.displaytarget_get_handle = dri_sw_displaytarget_get_handle; + +   /* texture functions */ +   ws->base.displaytarget_map = dri_sw_displaytarget_map; +   ws->base.displaytarget_unmap = dri_sw_displaytarget_unmap; + +   ws->base.displaytarget_display = dri_sw_displaytarget_display; + +   return &ws->base; +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.h b/src/gallium/winsys/sw/dri/dri_sw_winsys.h new file mode 100644 index 0000000000..329ac06a05 --- /dev/null +++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.h @@ -0,0 +1,38 @@ +/************************************************************************** + * + * Copyright 2009, VMware, Inc. + * All Rights Reserved. + * Copyright 2010 George Sapountzis <gsapountzis@gmail.com> + * + * 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 VMWARE 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 DRI_SW_WINSYS +#define DRI_SW_WINSYS + +#include "state_tracker/drisw_api.h" + +struct sw_winsys; + +struct sw_winsys *dri_create_sw_winsys(struct drisw_loader_funcs *lf); + +#endif diff --git a/src/gallium/winsys/sw/drm/Makefile b/src/gallium/winsys/sw/drm/Makefile new file mode 100644 index 0000000000..79664536aa --- /dev/null +++ b/src/gallium/winsys/sw/drm/Makefile @@ -0,0 +1,12 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = swdrm + +C_SOURCES = sw_drm_api.c + +LIBRARY_INCLUDES = + +LIBRARY_DEFINES = + +include ../../../Makefile.template diff --git a/src/gallium/winsys/sw/drm/SConscript b/src/gallium/winsys/sw/drm/SConscript new file mode 100644 index 0000000000..15a2e05d5a --- /dev/null +++ b/src/gallium/winsys/sw/drm/SConscript @@ -0,0 +1,21 @@ +####################################################################### +# SConscript for xlib winsys + + +Import('*') + +env = env.Clone() + +env.Append(CPPPATH = [ +    '#/src/gallium/include', +    '#/src/gallium/auxiliary', +    '#/src/gallium/drivers', +]) + +ws_drm = env.ConvenienceLibrary( +    target = 'ws_drm', +    source = [ +       'sw_drm_api.c', +    ] +) +Export('ws_drm') diff --git a/src/gallium/winsys/sw/drm/sw_drm_api.c b/src/gallium/winsys/sw/drm/sw_drm_api.c new file mode 100644 index 0000000000..7b86382619 --- /dev/null +++ b/src/gallium/winsys/sw/drm/sw_drm_api.c @@ -0,0 +1,103 @@ +/********************************************************** + * 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 "../../sw/wrapper/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 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); +   if (!screen) +      return NULL; + +   sww = wrapper_sw_winsys_warp_pipe_screen(screen); +   if (!sww) +      return NULL; + +   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); + +   if (!swapi) +      return api; + +   swapi->base.name = api->name; +   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/sw/drm/sw_drm_api.h b/src/gallium/winsys/sw/drm/sw_drm_api.h new file mode 100644 index 0000000000..ce90a04ae0 --- /dev/null +++ b/src/gallium/winsys/sw/drm/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/sw/fbdev/Makefile b/src/gallium/winsys/sw/fbdev/Makefile new file mode 100644 index 0000000000..8832aab193 --- /dev/null +++ b/src/gallium/winsys/sw/fbdev/Makefile @@ -0,0 +1,13 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = fbdev + +LIBRARY_INCLUDES = + +LIBRARY_DEFINES = + +C_SOURCES = \ +	fbdev_sw_winsys.c + +include ../../../Makefile.template diff --git a/src/gallium/winsys/sw/fbdev/SConscript b/src/gallium/winsys/sw/fbdev/SConscript new file mode 100644 index 0000000000..3b5b4ff1c0 --- /dev/null +++ b/src/gallium/winsys/sw/fbdev/SConscript @@ -0,0 +1,23 @@ +####################################################################### +# SConscript for fbdev winsys + + +Import('*') + +if env['platform'] == 'linux': + +    env = env.Clone() + +    env.Append(CPPPATH = [ +        '#/src/gallium/include', +        '#/src/gallium/auxiliary', +        '#/src/gallium/drivers', +    ]) + +    ws_fbdev = env.ConvenienceLibrary( +        target = 'ws_fbdev', +        source = [ +           'fbdev_sw_winsys.c', +        ] +    ) +    Export('ws_fbdev') diff --git a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c new file mode 100644 index 0000000000..f4f4cd7969 --- /dev/null +++ b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c @@ -0,0 +1,224 @@ +/* + * Mesa 3-D graphics library + * Version:  7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + *    Chia-I Wu <olv@lunarg.com> + */ + +#include <sys/mman.h> +#include <sys/ioctl.h> +#include <linux/fb.h> + +#include "pipe/p_compiler.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "state_tracker/sw_winsys.h" + +#include "fbdev_sw_winsys.h" + +struct fbdev_sw_displaytarget +{ +   enum pipe_format format; +   unsigned width; +   unsigned height; +   unsigned stride; + +   void *data; +   void *mapped; +}; + +struct fbdev_sw_winsys +{ +   struct sw_winsys base; + +   int fd; +   enum pipe_format format; + +   struct fb_fix_screeninfo finfo; +   void *fbmem; +   unsigned rows; +   unsigned stride; +}; + +static INLINE struct fbdev_sw_displaytarget * +fbdev_sw_displaytarget(struct sw_displaytarget *dt) +{ +   return (struct fbdev_sw_displaytarget *) dt; +} + +static INLINE struct fbdev_sw_winsys * +fbdev_sw_winsys(struct sw_winsys *ws) +{ +   return (struct fbdev_sw_winsys *) ws; +} + +static void +fbdev_displaytarget_display(struct sw_winsys *ws, +                            struct sw_displaytarget *dt, +                            void *context_private) +{ +   struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws); +   struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt); +   unsigned rows, len, i; + +   rows = MIN2(fbdt->height, fbdev->rows); +   len = util_format_get_stride(fbdt->format, fbdt->width); +   len = MIN2(len, fbdev->stride); + +   for (i = 0; i < rows; i++) { +      void *dst = fbdev->fbmem + fbdev->stride * i; +      void *src = fbdt->data + fbdt->stride * i; + +      memcpy(dst, src, len); +   } +} + +static void +fbdev_displaytarget_unmap(struct sw_winsys *ws, +                           struct sw_displaytarget *dt) +{ +   struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt); +   fbdt->mapped = NULL; +} + +static void * +fbdev_displaytarget_map(struct sw_winsys *ws, +                        struct sw_displaytarget *dt, +                        unsigned flags) +{ +   struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt); +   fbdt->mapped = fbdt->data; +   return fbdt->mapped; +} + +static void +fbdev_displaytarget_destroy(struct sw_winsys *ws, +                            struct sw_displaytarget *dt) +{ +   struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt); + +   if (fbdt->data) +      align_free(fbdt->data); + +   FREE(fbdt); +} + +static struct sw_displaytarget * +fbdev_displaytarget_create(struct sw_winsys *ws, +                           unsigned tex_usage, +                           enum pipe_format format, +                           unsigned width, unsigned height, +                           unsigned alignment, +                           unsigned *stride) +{ +   struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws); +   struct fbdev_sw_displaytarget *fbdt; +   unsigned nblocksy, size, format_stride; + +   if (fbdev->format != format) +      return NULL; + +   fbdt = CALLOC_STRUCT(fbdev_sw_displaytarget); +   if (!fbdt) +      return NULL; + +   fbdt->format = format; +   fbdt->width = width; +   fbdt->height = height; + +   format_stride = util_format_get_stride(format, width); +   fbdt->stride = align(format_stride, alignment); + +   nblocksy = util_format_get_nblocksy(format, height); +   size = fbdt->stride * nblocksy; + +   fbdt->data = align_malloc(size, alignment); +   if (!fbdt->data) { +      FREE(fbdt); +      return NULL; +   } + +   *stride = fbdt->stride; + +   return (struct sw_displaytarget *) fbdt; +} + +static boolean +fbdev_is_displaytarget_format_supported(struct sw_winsys *ws, +                                        unsigned tex_usage, +                                        enum pipe_format format) +{ +   struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws); +   return (fbdev->format == format); +} + +static void +fbdev_destroy(struct sw_winsys *ws) +{ +   struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws); + +   munmap(fbdev->fbmem, fbdev->finfo.smem_len); +   FREE(fbdev); +} + +struct sw_winsys * +fbdev_create_sw_winsys(int fd, enum pipe_format format) +{ +   struct fbdev_sw_winsys *fbdev; + +   fbdev = CALLOC_STRUCT(fbdev_sw_winsys); +   if (!fbdev) +      return NULL; + +   fbdev->fd = fd; +   fbdev->format = format; +   if (ioctl(fbdev->fd, FBIOGET_FSCREENINFO, &fbdev->finfo)) { +      FREE(fbdev); +      return NULL; +   } + +   fbdev->fbmem = mmap(0, fbdev->finfo.smem_len, +         PROT_WRITE, MAP_SHARED, fbdev->fd, 0); +   if (fbdev->fbmem == MAP_FAILED) { +      FREE(fbdev); +      return NULL; +   } + +   fbdev->rows = fbdev->finfo.smem_len / fbdev->finfo.line_length; +   fbdev->stride = fbdev->finfo.line_length; + +   fbdev->base.destroy = fbdev_destroy; +   fbdev->base.is_displaytarget_format_supported = +      fbdev_is_displaytarget_format_supported; + +   fbdev->base.displaytarget_create = fbdev_displaytarget_create; +   fbdev->base.displaytarget_destroy = fbdev_displaytarget_destroy; +   fbdev->base.displaytarget_map = fbdev_displaytarget_map; +   fbdev->base.displaytarget_unmap = fbdev_displaytarget_unmap; + +   fbdev->base.displaytarget_display = fbdev_displaytarget_display; + +   return &fbdev->base; +} diff --git a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h new file mode 100644 index 0000000000..d958ab9db3 --- /dev/null +++ b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h @@ -0,0 +1,38 @@ +/* + * Mesa 3-D graphics library + * Version:  7.8 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + *    Chia-I Wu <olv@lunarg.com> + */ + +#ifndef FBDEV_SW_WINSYS +#define FBDEV_SW_WINSYS + +struct sw_winsys; +enum pipe_format; + +struct sw_winsys * +fbdev_create_sw_winsys(int fd, enum pipe_format format); + +#endif /* FBDEV_SW_WINSYS */ diff --git a/src/gallium/winsys/sw/gdi/SConscript b/src/gallium/winsys/sw/gdi/SConscript new file mode 100644 index 0000000000..1267fc6eea --- /dev/null +++ b/src/gallium/winsys/sw/gdi/SConscript @@ -0,0 +1,23 @@ +####################################################################### +# SConscript for xlib winsys + + +Import('*') + +if env['platform'] == 'windows': + +    env = env.Clone() + +    env.Append(CPPPATH = [ +        '#/src/gallium/include', +        '#/src/gallium/auxiliary', +        '#/src/gallium/drivers', +    ]) + +    ws_gdi = env.ConvenienceLibrary( +        target = 'ws_gdi', +        source = [ +           'gdi_sw_winsys.c', +        ] +    ) +    Export('ws_gdi') diff --git a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c new file mode 100644 index 0000000000..2e12f6e6cc --- /dev/null +++ b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c @@ -0,0 +1,247 @@ +/************************************************************************** + * + * Copyright 2009 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, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * @file + * GDI software rasterizer support. + * + * @author Jose Fonseca <jfonseca@vmware.com> + */ + + +#include <windows.h> + +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "state_tracker/sw_winsys.h" +#include "gdi_sw_winsys.h" + + +struct gdi_sw_displaytarget +{ +   enum pipe_format format; +   unsigned width; +   unsigned height; +   unsigned stride; + +   unsigned size; + +   void *data; + +   BITMAPINFO bmi; +}; + + +/** Cast wrapper */ +static INLINE struct gdi_sw_displaytarget * +gdi_sw_displaytarget( struct sw_displaytarget *buf ) +{ +   return (struct gdi_sw_displaytarget *)buf; +} + + +static boolean +gdi_sw_is_displaytarget_format_supported( struct sw_winsys *ws, +                                                unsigned tex_usage, +                                                enum pipe_format format ) +{ +   switch(format) { +   case PIPE_FORMAT_B8G8R8X8_UNORM: +   case PIPE_FORMAT_B8G8R8A8_UNORM: +      return TRUE; + +   /* TODO: Support other formats possible with BMPs, as described in  +    * http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx */ +       +   default: +      return FALSE; +   } +} + + +static void * +gdi_sw_displaytarget_map(struct sw_winsys *ws, +                               struct sw_displaytarget *dt, +                               unsigned flags ) +{ +   struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt); + +   return gdt->data; +} + + +static void +gdi_sw_displaytarget_unmap(struct sw_winsys *ws, +                                 struct sw_displaytarget *dt ) +{ + +} + + +static void +gdi_sw_displaytarget_destroy(struct sw_winsys *winsys, +                                   struct sw_displaytarget *dt) +{ +   struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt); + +   align_free(gdt->data); +   FREE(gdt); +} + + +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, +                                  unsigned *stride) +{ +   struct gdi_sw_displaytarget *gdt; +   unsigned cpp; +   unsigned bpp; +    +   gdt = CALLOC_STRUCT(gdi_sw_displaytarget); +   if(!gdt) +      goto no_gdt; + +   gdt->format = format; +   gdt->width = width; +   gdt->height = height; + +   bpp = util_format_get_blocksizebits(format); +   cpp = util_format_get_blocksize(format); +    +   gdt->stride = align(width * cpp, alignment); +   gdt->size = gdt->stride * height; +    +   gdt->data = align_malloc(gdt->size, alignment); +   if(!gdt->data) +      goto no_data; + +   gdt->bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); +   gdt->bmi.bmiHeader.biWidth = gdt->stride / cpp; +   gdt->bmi.bmiHeader.biHeight= -(long)height; +   gdt->bmi.bmiHeader.biPlanes = 1; +   gdt->bmi.bmiHeader.biBitCount = bpp; +   gdt->bmi.bmiHeader.biCompression = BI_RGB; +   gdt->bmi.bmiHeader.biSizeImage = 0; +   gdt->bmi.bmiHeader.biXPelsPerMeter = 0; +   gdt->bmi.bmiHeader.biYPelsPerMeter = 0; +   gdt->bmi.bmiHeader.biClrUsed = 0; +   gdt->bmi.bmiHeader.biClrImportant = 0; + +   *stride = gdt->stride; +   return (struct sw_displaytarget *)gdt; + +no_data: +   FREE(gdt); +no_gdt: +   return NULL; +} + + +static struct sw_displaytarget * +gdi_sw_displaytarget_from_handle(struct sw_winsys *winsys, +                                 const struct pipe_resource *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, +                HDC hDC ) +{ +    struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt); + +    StretchDIBits(hDC, +                  0, 0, gdt->width, gdt->height, +                  0, 0, gdt->width, gdt->height, +                  gdt->data, &gdt->bmi, 0, SRCCOPY); +} + +static void +gdi_sw_displaytarget_display(struct sw_winsys *winsys,  +                             struct sw_displaytarget *dt, +                             void *context_private) +{ +    /* nasty: +     */ +    HDC hDC = (HDC)context_private; + +    gdi_sw_display(winsys, dt, hDC); +} + + +static void +gdi_sw_destroy(struct sw_winsys *winsys) +{ +   FREE(winsys); +} + +struct sw_winsys * +gdi_create_sw_winsys(void) +{ +   static struct sw_winsys *winsys; + +   winsys = CALLOC_STRUCT(sw_winsys); +   if(!winsys) +      return NULL; + +   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; +   winsys->displaytarget_destroy = gdi_sw_displaytarget_destroy; + +   return winsys; +} + diff --git a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h new file mode 100644 index 0000000000..4bbcb47848 --- /dev/null +++ b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h @@ -0,0 +1,16 @@ +#ifndef GDI_SW_WINSYS_H +#define GDI_SW_WINSYS_H + +#include <windows.h> + +#include "pipe/p_compiler.h" +#include "state_tracker/sw_winsys.h" + +void gdi_sw_display( struct sw_winsys *winsys, +                     struct sw_displaytarget *dt, +                     HDC hDC ); + +struct sw_winsys * +gdi_create_sw_winsys(void); + +#endif diff --git a/src/gallium/winsys/sw/null/Makefile b/src/gallium/winsys/sw/null/Makefile new file mode 100644 index 0000000000..b1882b582e --- /dev/null +++ b/src/gallium/winsys/sw/null/Makefile @@ -0,0 +1,16 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = ws_null + +LIBRARY_INCLUDES = \ +	-I$(TOP)/src/gallium/include \ +	-I$(TOP)/src/gallium/drivers \ +	-I$(TOP)/src/gallium/auxiliary + +C_SOURCES = \ +	null_sw_winsys.c  + +include ../../../Makefile.template + + diff --git a/src/gallium/winsys/sw/null/SConscript b/src/gallium/winsys/sw/null/SConscript new file mode 100644 index 0000000000..21837dc60c --- /dev/null +++ b/src/gallium/winsys/sw/null/SConscript @@ -0,0 +1,21 @@ +####################################################################### +# SConscript for xlib winsys + + +Import('*') + +env = env.Clone() + +env.Append(CPPPATH = [ +    '#/src/gallium/include', +    '#/src/gallium/auxiliary', +    '#/src/gallium/drivers', +]) + +ws_null = env.ConvenienceLibrary( +    target = 'ws_null', +    source = [ +       'null_sw_winsys.c', +    ] +) +Export('ws_null') diff --git a/src/gallium/winsys/sw/null/null_sw_winsys.c b/src/gallium/winsys/sw/null/null_sw_winsys.c new file mode 100644 index 0000000000..157efa9973 --- /dev/null +++ b/src/gallium/winsys/sw/null/null_sw_winsys.c @@ -0,0 +1,148 @@ +/************************************************************************** + *  + * 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, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + *  + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR  + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + *  + **************************************************************************/ + +/** + * @file + * Null software rasterizer winsys. + *  + * There is no present support. Framebuffer data needs to be obtained via + * transfers. + * + * @author Jose Fonseca + */ + + +#include "pipe/p_format.h" +#include "util/u_memory.h" +#include "state_tracker/sw_winsys.h" +#include "null_sw_winsys.h" + + +static boolean +null_sw_is_displaytarget_format_supported(struct sw_winsys *ws, +                                          unsigned tex_usage, +                                          enum pipe_format format ) +{ +   return FALSE; +} + + +static void * +null_sw_displaytarget_map(struct sw_winsys *ws, +                          struct sw_displaytarget *dt, +                          unsigned flags ) +{ +   assert(0); +   return NULL; +} + + +static void +null_sw_displaytarget_unmap(struct sw_winsys *ws, +                            struct sw_displaytarget *dt ) +{ +   assert(0); +} + + +static void +null_sw_displaytarget_destroy(struct sw_winsys *winsys, +                              struct sw_displaytarget *dt) +{ +   assert(0); +} + + +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, +                             unsigned *stride) +{ +   return NULL; +} + + +static struct sw_displaytarget * +null_sw_displaytarget_from_handle(struct sw_winsys *winsys, +                                  const struct pipe_resource *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, +                              void *context_private) +{ +   assert(0); +} + + +static void +null_sw_destroy(struct sw_winsys *winsys) +{ +   FREE(winsys); +} + + +struct sw_winsys * +null_sw_create(void) +{ +   static struct sw_winsys *winsys; + +   winsys = CALLOC_STRUCT(sw_winsys); +   if (!winsys) +      return NULL; + +   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; +   winsys->displaytarget_destroy = null_sw_displaytarget_destroy; + +   return winsys; +} diff --git a/src/gallium/winsys/sw/null/null_sw_winsys.h b/src/gallium/winsys/sw/null/null_sw_winsys.h new file mode 100644 index 0000000000..1986186feb --- /dev/null +++ b/src/gallium/winsys/sw/null/null_sw_winsys.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * 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, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + + +#ifndef NULL_SW_WINSYS_H_ +#define NULL_SW_WINSYS_H_ + + +struct sw_winsys; + + +struct sw_winsys * +null_sw_create(void); + + +#endif /* NULL_SW_WINSYS_H_ */ diff --git a/src/gallium/winsys/sw/wrapper/Makefile b/src/gallium/winsys/sw/wrapper/Makefile new file mode 100644 index 0000000000..4771fbcf70 --- /dev/null +++ b/src/gallium/winsys/sw/wrapper/Makefile @@ -0,0 +1,12 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = wsw + +C_SOURCES = wrapper_sw_winsys.c + +LIBRARY_INCLUDES = + +LIBRARY_DEFINES = + +include ../../../Makefile.template diff --git a/src/gallium/winsys/sw/wrapper/SConscript b/src/gallium/winsys/sw/wrapper/SConscript new file mode 100644 index 0000000000..4c60488df0 --- /dev/null +++ b/src/gallium/winsys/sw/wrapper/SConscript @@ -0,0 +1,21 @@ +####################################################################### +# SConscript for xlib winsys + + +Import('*') + +env = env.Clone() + +env.Append(CPPPATH = [ +    '#/src/gallium/include', +    '#/src/gallium/auxiliary', +    '#/src/gallium/drivers', +]) + +ws_wrapper = env.ConvenienceLibrary( +    target = 'ws_wrapper', +    source = [ +       'wrapper_sw_winsys.c', +    ] +) +Export('ws_wrapper') diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c new file mode 100644 index 0000000000..b997abda9b --- /dev/null +++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c @@ -0,0 +1,300 @@ +/********************************************************** + * 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_resource *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_resource *tex = wdt->tex; +   struct pipe_transfer *tr; + +   tr = pipe_get_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->transfer_destroy(pipe, tr); + +   return TRUE; +} + +static struct sw_displaytarget * +wsw_dt_wrap_texture(struct wrapper_sw_winsys *wsw, +                    struct pipe_resource *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_resource_reference(&tex, NULL); +   return NULL; +} + +static struct sw_displaytarget * +wsw_dt_create(struct sw_winsys *ws, +              unsigned bind, +              enum pipe_format format, +              unsigned width, unsigned height, +              unsigned alignment, +              unsigned *stride) +{ +   struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws); +   struct pipe_resource templ; +   struct pipe_resource *tex; + +   /* +    * XXX Why don't we just get the template. +    */ +   memset(&templ, 0, sizeof(templ)); +   templ.target = PIPE_TEXTURE_2D; +   templ.width0 = width; +   templ.height0 = height; +   templ.format = format; +   templ.bind = bind; + +   /* XXX alignment: we can't do anything about this */ + +   tex = wsw->screen->resource_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_resource *templ, +                   struct winsys_handle *whandle, +                   unsigned *stride) +{ +   struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws); +   struct pipe_resource *tex; + +   tex = wsw->screen->resource_from_handle(wsw->screen, templ, whandle); +   if (!tex) +      return NULL; + +   return wsw_dt_wrap_texture(wsw, tex, stride); +} + +static boolean +wsw_dt_get_handle(struct sw_winsys *ws, +                  struct sw_displaytarget *dt, +                  struct winsys_handle *whandle) +{ +   struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws); +   struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt); +   struct pipe_resource *tex = wdt->tex; + +   return wsw->screen->resource_get_handle(wsw->screen, tex, whandle); +} + +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_resource *tex = wdt->tex; +   struct pipe_transfer *tr; +   void *ptr; + +   if (!wdt->map_count) { + +      assert(!wdt->transfer); + +      tr = pipe_get_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->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->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_resource_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); + +   if (!wsw) +      goto err; + +   wsw->base.displaytarget_create = wsw_dt_create; +   wsw->base.displaytarget_from_handle = wsw_dt_from_handle; +   wsw->base.displaytarget_get_handle = wsw_dt_get_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_free; + +   return &wsw->base; + +err_free: +   FREE(wsw); +err: +   return NULL; +} diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h new file mode 100644 index 0000000000..b5c25a3c50 --- /dev/null +++ b/src/gallium/winsys/sw/wrapper/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/sw/xlib/Makefile b/src/gallium/winsys/sw/xlib/Makefile new file mode 100644 index 0000000000..c669389928 --- /dev/null +++ b/src/gallium/winsys/sw/xlib/Makefile @@ -0,0 +1,17 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = ws_xlib + +LIBRARY_INCLUDES = \ +	-I$(TOP)/src/gallium/include \ +	-I$(TOP)/src/gallium/drivers \ +	-I$(TOP)/src/gallium/auxiliary \ +	$(X11_CFLAGS) + +C_SOURCES = \ +	xlib_sw_winsys.c  + +include ../../../Makefile.template + + diff --git a/src/gallium/winsys/sw/xlib/SConscript b/src/gallium/winsys/sw/xlib/SConscript new file mode 100644 index 0000000000..2af6153b4c --- /dev/null +++ b/src/gallium/winsys/sw/xlib/SConscript @@ -0,0 +1,23 @@ +####################################################################### +# SConscript for xlib winsys + + +Import('*') + +if env['platform'] == 'linux': + +    env = env.Clone() + +    env.Append(CPPPATH = [ +        '#/src/gallium/include', +        '#/src/gallium/auxiliary', +        '#/src/gallium/drivers', +    ]) + +    ws_xlib = env.ConvenienceLibrary( +        target = 'ws_xlib', +        source = [ +           'xlib_sw_winsys.c', +        ] +    ) +    Export('ws_xlib') diff --git a/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c new file mode 100644 index 0000000000..b78f537c12 --- /dev/null +++ b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c @@ -0,0 +1,473 @@ +/************************************************************************** + *  + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + *  + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + *  + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR  + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + *  + *  + **************************************************************************/ + +/* + * Authors: + *   Keith Whitwell + *   Brian Paul + */ + +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "state_tracker/xlib_sw_winsys.h" + +#include <X11/Xlib.h> +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <X11/extensions/XShm.h> + +DEBUG_GET_ONCE_BOOL_OPTION(xlib_no_shm, "XLIB_NO_SHM", FALSE) + +/** + * Display target for Xlib winsys. + * Low-level OS/window system memory buffer + */ +struct xm_displaytarget +{ +   enum pipe_format format; +   unsigned width; +   unsigned height; +   unsigned stride; + +   void *data; +   void *mapped; + +   Display *display; +   Visual *visual; +   XImage *tempImage; +   GC gc; + +   /* This is the last drawable that this display target was presented +    * against.  May need to recreate gc, tempImage when this changes?? +    */ +   Drawable drawable; + +   XShmSegmentInfo shminfo; +   int shm; +}; + + +/** + * Subclass of sw_winsys for Xlib winsys + */ +struct xlib_sw_winsys +{ +   struct sw_winsys base; + + + +   Display *display; +}; + + + +/** Cast wrapper */ +static INLINE struct xm_displaytarget * +xm_displaytarget( struct sw_displaytarget *dt ) +{ +   return (struct xm_displaytarget *)dt; +} + + +/** + * X Shared Memory Image extension code + */ + +static volatile int mesaXErrorFlag = 0; + +/** + * Catches potential Xlib errors. + */ +static int +mesaHandleXError(Display *dpy, XErrorEvent *event) +{ +   (void) dpy; +   (void) event; +   mesaXErrorFlag = 1; +   return 0; +} + + +static char *alloc_shm(struct xm_displaytarget *buf, unsigned size) +{ +   XShmSegmentInfo *const shminfo = & buf->shminfo; + +   shminfo->shmid = -1; +   shminfo->shmaddr = (char *) -1; + +   shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); +   if (shminfo->shmid < 0) { +      return NULL; +   } + +   shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); +   if (shminfo->shmaddr == (char *) -1) { +      shmctl(shminfo->shmid, IPC_RMID, 0); +      return NULL; +   } + +   shminfo->readOnly = False; +   return shminfo->shmaddr; +} + + +/** + * Allocate a shared memory XImage back buffer for the given XMesaBuffer. + */ +static void +alloc_shm_ximage(struct xm_displaytarget *xm_dt, +                 struct xlib_drawable *xmb, +                 unsigned width, unsigned height) +{ +   /* +    * We have to do a _lot_ of error checking here to be sure we can +    * really use the XSHM extension.  It seems different servers trigger +    * errors at different points if the extension won't work.  Therefore +    * we have to be very careful... +    */ +   int (*old_handler)(Display *, XErrorEvent *); + +   xm_dt->tempImage = XShmCreateImage(xm_dt->display, +                                      xmb->visual, +                                      xmb->depth, +                                      ZPixmap, +                                      NULL, +                                      &xm_dt->shminfo, +                                      width, height); +   if (xm_dt->tempImage == NULL) { +      xm_dt->shm = 0; +      return; +   } + + +   mesaXErrorFlag = 0; +   old_handler = XSetErrorHandler(mesaHandleXError); +   /* This may trigger the X protocol error we're ready to catch: */ +   XShmAttach(xm_dt->display, &xm_dt->shminfo); +   XSync(xm_dt->display, False); + +   if (mesaXErrorFlag) { +      /* we are on a remote display, this error is normal, don't print it */ +      XFlush(xm_dt->display); +      mesaXErrorFlag = 0; +      XDestroyImage(xm_dt->tempImage); +      xm_dt->tempImage = NULL; +      xm_dt->shm = 0; +      (void) XSetErrorHandler(old_handler); +      return; +   } + +   xm_dt->shm = 1; +} + + +static void +alloc_ximage(struct xm_displaytarget *xm_dt, +             struct xlib_drawable *xmb, +             unsigned width, unsigned height) +{ +   if (xm_dt->shm) { +      alloc_shm_ximage(xm_dt, xmb, width, height); +      return; +   } + +   xm_dt->tempImage = XCreateImage(xm_dt->display, +                                   xmb->visual, +                                   xmb->depth, +                                   ZPixmap, 0, +                                   NULL, width, height, +                                   8, 0); +} + +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 */ +   return TRUE; +} + + +static void * +xm_displaytarget_map(struct sw_winsys *ws, +                     struct sw_displaytarget *dt, +                     unsigned flags) +{ +   struct xm_displaytarget *xm_dt = xm_displaytarget(dt); +   xm_dt->mapped = xm_dt->data; +   return xm_dt->mapped; +} + +static void +xm_displaytarget_unmap(struct sw_winsys *ws, +                       struct sw_displaytarget *dt) +{ +   struct xm_displaytarget *xm_dt = xm_displaytarget(dt); +   xm_dt->mapped = NULL; +} + +static void +xm_displaytarget_destroy(struct sw_winsys *ws, +                         struct sw_displaytarget *dt) +{ +   struct xm_displaytarget *xm_dt = xm_displaytarget(dt); + +   if (xm_dt->data) { +      if (xm_dt->shminfo.shmid >= 0) { +         shmdt(xm_dt->shminfo.shmaddr); +         shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0); +          +         xm_dt->shminfo.shmid = -1; +         xm_dt->shminfo.shmaddr = (char *) -1; +      } +      else { +         FREE(xm_dt->data); +         if (xm_dt->tempImage && xm_dt->tempImage->data == xm_dt->data) { +            xm_dt->tempImage->data = NULL; +         } +         xm_dt->data = NULL; +      } +   } + +   if (xm_dt->tempImage) { +      XDestroyImage(xm_dt->tempImage); +      xm_dt->tempImage = NULL; +   } + +   if (xm_dt->gc) +      XFreeGC(xm_dt->display, xm_dt->gc); + +   FREE(xm_dt); +} + + +/** + * Display/copy the image in the surface into the X window specified + * by the XMesaBuffer. + */ +static void +xlib_sw_display(struct xlib_drawable *xlib_drawable, +                struct sw_displaytarget *dt) +{ +   static boolean no_swap = 0; +   static boolean firsttime = 1; +   struct xm_displaytarget *xm_dt = xm_displaytarget(dt); +   Display *display = xm_dt->display; +   XImage *ximage; + +   if (firsttime) { +      no_swap = getenv("SP_NO_RAST") != NULL; +      firsttime = 0; +   } + +   if (no_swap) +      return; + +   if (xm_dt->drawable != xlib_drawable->drawable) { +      if (xm_dt->gc) { +         XFreeGC( display, xm_dt->gc ); +         xm_dt->gc = NULL; +      } + +      if (xm_dt->tempImage) { +         XDestroyImage( xm_dt->tempImage ); +         xm_dt->tempImage = NULL; +      } + +      xm_dt->drawable = xlib_drawable->drawable; +   } + +   if (xm_dt->tempImage == NULL) { +      assert(util_format_get_blockwidth(xm_dt->format) == 1); +      assert(util_format_get_blockheight(xm_dt->format) == 1); +      alloc_ximage(xm_dt, xlib_drawable, +                   xm_dt->stride / util_format_get_blocksize(xm_dt->format), +                   xm_dt->height); +      if (!xm_dt->tempImage) +         return; +   } + +   if (xm_dt->gc == NULL) { +      xm_dt->gc = XCreateGC( display, xlib_drawable->drawable, 0, NULL ); +      XSetFunction( display, xm_dt->gc, GXcopy ); +   } + +   if (xm_dt->shm) +   { +      ximage = xm_dt->tempImage; +      ximage->data = xm_dt->data; + +      /* _debug_printf("XSHM\n"); */ +      XShmPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc, +                   ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False); +   } +   else { +      /* display image in Window */ +      ximage = xm_dt->tempImage; +      ximage->data = xm_dt->data; + +      /* check that the XImage has been previously initialized */ +      assert(ximage->format); +      assert(ximage->bitmap_unit); + +      /* update XImage's fields */ +      ximage->width = xm_dt->width; +      ximage->height = xm_dt->height; +      ximage->bytes_per_line = xm_dt->stride; + +      /* _debug_printf("XPUT\n"); */ +      XPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc, +                ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height); +   } + +   XFlush(xm_dt->display); +} + +/** + * Display/copy the image in the surface into the X window specified + * by the XMesaBuffer. + */ +static void +xm_displaytarget_display(struct sw_winsys *ws, +                         struct sw_displaytarget *dt, +                         void *context_private) +{ +   struct xlib_drawable *xlib_drawable = (struct xlib_drawable *)context_private; +   xlib_sw_display(xlib_drawable, dt); +} + + +static struct sw_displaytarget * +xm_displaytarget_create(struct sw_winsys *winsys, +                        unsigned tex_usage, +                        enum pipe_format format, +                        unsigned width, unsigned height, +                        unsigned alignment, +                        unsigned *stride) +{ +   struct xm_displaytarget *xm_dt; +   unsigned nblocksy, size; + +   xm_dt = CALLOC_STRUCT(xm_displaytarget); +   if(!xm_dt) +      goto no_xm_dt; + +   xm_dt->display = ((struct xlib_sw_winsys *)winsys)->display; +   xm_dt->format = format; +   xm_dt->width = width; +   xm_dt->height = height; + +   nblocksy = util_format_get_nblocksy(format, height); +   xm_dt->stride = align(util_format_get_stride(format, width), alignment); +   size = xm_dt->stride * nblocksy; + +   if (!debug_get_option_xlib_no_shm()) { +      xm_dt->data = alloc_shm(xm_dt, size); +      if (xm_dt->data) { +         xm_dt->shm = TRUE; +      } +   } + +   if(!xm_dt->data) { +      xm_dt->data = align_malloc(size, alignment); +      if(!xm_dt->data) +         goto no_data; +   } + +   *stride = xm_dt->stride; +   return (struct sw_displaytarget *)xm_dt; + +no_data: +   FREE(xm_dt); +no_xm_dt: +   return NULL; +} + + +static struct sw_displaytarget * +xm_displaytarget_from_handle(struct sw_winsys *winsys, +                             const struct pipe_resource *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 ) +{ +   FREE(ws); +} + + +struct sw_winsys * +xlib_create_sw_winsys( Display *display ) +{ +   struct xlib_sw_winsys *ws; + +   ws = CALLOC_STRUCT(xlib_sw_winsys); +   if (!ws) +      return NULL; + +   ws->display = display; +   ws->base.destroy = xm_destroy; + +   ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported; + +   ws->base.displaytarget_create = xm_displaytarget_create; +   ws->base.displaytarget_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; + +   ws->base.displaytarget_display = xm_displaytarget_display; + +   return &ws->base; +} + | 
