softpipe: rework to use the llvmpipe winsys
authorKeith Whitwell <keithw@vmware.com>
Thu, 4 Mar 2010 16:09:33 +0000 (16:09 +0000)
committerKeith Whitwell <keithw@vmware.com>
Thu, 4 Mar 2010 16:09:33 +0000 (16:09 +0000)
Promote the llvmpipe winsys more or less unchanged to
state_trackers/sw_winsys.h.

Some minor breakages:
  - softpipe::texture_blanket is broken, but scheduled for removal anyway.
  - haven't fixed up g3vdl yet.

30 files changed:
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/llvmpipe/lp_screen.h
src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/llvmpipe/lp_texture.c
src/gallium/drivers/llvmpipe/lp_texture.h
src/gallium/drivers/llvmpipe/lp_winsys.h [deleted file]
src/gallium/drivers/softpipe/Makefile
src/gallium/drivers/softpipe/SConscript
src/gallium/drivers/softpipe/sp_buffer.c [new file with mode: 0644]
src/gallium/drivers/softpipe/sp_buffer.h [new file with mode: 0644]
src/gallium/drivers/softpipe/sp_context.c
src/gallium/drivers/softpipe/sp_draw_arrays.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/softpipe/sp_screen.h
src/gallium/drivers/softpipe/sp_state_fs.c
src/gallium/drivers/softpipe/sp_texture.c
src/gallium/drivers/softpipe/sp_texture.h
src/gallium/drivers/softpipe/sp_winsys.c [deleted file]
src/gallium/drivers/softpipe/sp_winsys.h [deleted file]
src/gallium/include/state_tracker/sw_winsys.h [new file with mode: 0644]
src/gallium/winsys/gdi/SConscript
src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
src/gallium/winsys/gdi/gdi_softpipe_winsys.c
src/gallium/winsys/xlib/Makefile
src/gallium/winsys/xlib/SConscript
src/gallium/winsys/xlib/xlib.c
src/gallium/winsys/xlib/xlib.h
src/gallium/winsys/xlib/xlib_llvmpipe.c
src/gallium/winsys/xlib/xlib_softpipe.c
src/gallium/winsys/xlib/xlib_sw_winsys.c [new file with mode: 0644]

index f84ede675b3145c96b5a2bb6263b23cbf03e7a9c..8816440a509d04bae47705e672ecbda7560418b8 100644 (file)
@@ -167,7 +167,7 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
                               unsigned geom_flags )
 {
    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
-   struct llvmpipe_winsys *winsys = screen->winsys;
+   struct sw_winsys *winsys = screen->winsys;
    const struct util_format_description *format_desc;
 
    format_desc = util_format_description(format);
@@ -258,7 +258,7 @@ llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
                            void *context_private)
 {
    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
-   struct llvmpipe_winsys *winsys = screen->winsys;
+   struct sw_winsys *winsys = screen->winsys;
    struct llvmpipe_texture *texture = llvmpipe_texture(surface->texture);
 
    assert(texture->dt);
@@ -271,7 +271,7 @@ static void
 llvmpipe_destroy_screen( struct pipe_screen *_screen )
 {
    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
-   struct llvmpipe_winsys *winsys = screen->winsys;
+   struct sw_winsys *winsys = screen->winsys;
 
    lp_jit_screen_cleanup(screen);
 
@@ -288,7 +288,7 @@ llvmpipe_destroy_screen( struct pipe_screen *_screen )
  * Note: we're not presently subclassing pipe_screen (no llvmpipe_screen).
  */
 struct pipe_screen *
-llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
+llvmpipe_create_screen(struct sw_winsys *winsys)
 {
    struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
 
index 4a1b4d6f3e21ce727aec6cc35c342f635338875f..3211822b53efe97b0c0d281cde63d8ae93c53d34 100644 (file)
 #include "pipe/p_defines.h"
 
 
-struct llvmpipe_winsys;
+struct sw_winsys;
 
 
 struct llvmpipe_screen
 {
    struct pipe_screen base;
 
-   struct llvmpipe_winsys *winsys;
+   struct sw_winsys *winsys;
 
    LLVMModuleRef module;
    LLVMExecutionEngineRef engine;
index aebed85fbbd6726fd7a83c94c5f9406fd665c515..72b19d0b05cf50dacb25bcda3e40bf2835a14353 100644 (file)
@@ -479,7 +479,7 @@ lp_setup_set_sampler_textures( struct setup_context *setup,
              */
 
             struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
-            struct llvmpipe_winsys *winsys = screen->winsys;
+            struct sw_winsys *winsys = screen->winsys;
             jit_tex->data = winsys->displaytarget_map(winsys, lp_tex->dt,
                                                       PIPE_BUFFER_USAGE_CPU_READ);
             assert(jit_tex->data);
index 7f45635542897470e7606f6ca60624194d16d964..aed9ed6175dfe8388b2bd1f0e37c3d49258f907a 100644 (file)
@@ -93,7 +93,7 @@ static boolean
 llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
                               struct llvmpipe_texture *lpt)
 {
-   struct llvmpipe_winsys *winsys = screen->winsys;
+   struct sw_winsys *winsys = screen->winsys;
 
    /* Round up the surface size to a multiple of the tile size to
     * avoid tile clipping.
@@ -187,7 +187,7 @@ llvmpipe_texture_destroy(struct pipe_texture *pt)
 
    if (lpt->dt) {
       /* display target */
-      struct llvmpipe_winsys *winsys = screen->winsys;
+      struct sw_winsys *winsys = screen->winsys;
       winsys->displaytarget_destroy(winsys, lpt->dt);
    }
    else {
@@ -357,7 +357,7 @@ llvmpipe_transfer_map( struct pipe_screen *_screen,
 
    if (lpt->dt) {
       /* display target */
-      struct llvmpipe_winsys *winsys = screen->winsys;
+      struct sw_winsys *winsys = screen->winsys;
 
       map = winsys->displaytarget_map(winsys, lpt->dt,
                                       pipe_transfer_buffer_flags(transfer));
@@ -398,7 +398,7 @@ llvmpipe_transfer_unmap(struct pipe_screen *screen,
 
    if (lpt->dt) {
       /* display target */
-      struct llvmpipe_winsys *winsys = lp_screen->winsys;
+      struct sw_winsys *winsys = lp_screen->winsys;
       winsys->displaytarget_unmap(winsys, lpt->dt);
    }
 }
index 87c905bc027028cdd69fd9b9cf1bc8c9b0ab9d13..6a6d9f9222f4cafe49f7729493ecd04e73f41a33 100644 (file)
@@ -35,7 +35,8 @@
 struct pipe_context;
 struct pipe_screen;
 struct llvmpipe_context;
-struct llvmpipe_displaytarget;
+
+struct sw_displaytarget;
 
 
 struct llvmpipe_texture
@@ -49,7 +50,7 @@ struct llvmpipe_texture
     * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
     * usage.
     */
-   struct llvmpipe_displaytarget *dt;
+   struct sw_displaytarget *dt;
 
    /**
     * Malloc'ed data for regular textures, or a mapping to dt above.
diff --git a/src/gallium/drivers/llvmpipe/lp_winsys.h b/src/gallium/drivers/llvmpipe/lp_winsys.h
deleted file mode 100644 (file)
index ce11fa9..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007-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 above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/**
- * @file
- * llvmpipe public interface.
- */
-
-
-#ifndef LP_WINSYS_H
-#define LP_WINSYS_H
-
-
-#include "pipe/p_compiler.h" /* for boolean */
-#include "pipe/p_format.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-struct pipe_screen;
-struct pipe_context;
-
-
-/**
- * Opaque pointer.
- */
-struct llvmpipe_displaytarget;
-
-
-/**
- * This is the interface that llvmpipe expects any window system
- * hosting it to implement.
- * 
- * llvmpipe is for the most part a self sufficient driver. The only thing it
- * does not know is how to display a surface.
- */
-struct llvmpipe_winsys
-{
-   void 
-   (*destroy)( struct llvmpipe_winsys *ws );
-
-   boolean
-   (*is_displaytarget_format_supported)( struct llvmpipe_winsys *ws,
-                                         enum pipe_format format );
-   
-   /**
-    * Allocate storage for a render target.
-    * 
-    * Often surfaces which are meant to be blitted to the front screen (i.e.,
-    * display targets) must be allocated with special characteristics, memory 
-    * pools, or obtained directly from the windowing system.
-    *  
-    * This callback is invoked by the pipe_screen when creating a texture marked
-    * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying 
-    * storage.
-    */
-   struct llvmpipe_displaytarget *
-   (*displaytarget_create)( struct llvmpipe_winsys *ws,
-                            enum pipe_format format,
-                            unsigned width, unsigned height,
-                            unsigned alignment,
-                            unsigned *stride );
-
-   void *
-   (*displaytarget_map)( struct llvmpipe_winsys *ws, 
-                         struct llvmpipe_displaytarget *dt,
-                         unsigned flags );
-
-   void
-   (*displaytarget_unmap)( struct llvmpipe_winsys *ws,
-                           struct llvmpipe_displaytarget *dt );
-
-   /**
-    * @sa pipe_screen:flush_frontbuffer.
-    *
-    * This call will likely become asynchronous eventually.
-    */
-   void
-   (*displaytarget_display)( struct llvmpipe_winsys *ws, 
-                             struct llvmpipe_displaytarget *dt,
-                             void *context_private );
-
-   void 
-   (*displaytarget_destroy)( struct llvmpipe_winsys *ws, 
-                             struct llvmpipe_displaytarget *dt );
-};
-
-
-
-struct pipe_screen *
-llvmpipe_create_screen( struct llvmpipe_winsys * );
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LP_WINSYS_H */
index e4ac49fa85f40a49f6f095ec13e4c68f3bd0d66b..1c6e4ae0768e235ec5b48617aa767649774f447f 100644 (file)
@@ -6,6 +6,7 @@ LIBNAME = softpipe
 C_SOURCES = \
        sp_fs_exec.c \
        sp_fs_sse.c \
+       sp_buffer.c \
        sp_clear.c \
        sp_flush.c \
        sp_query.c \
@@ -32,7 +33,6 @@ C_SOURCES = \
        sp_tex_tile_cache.c \
        sp_tile_cache.c \
        sp_surface.c \
-       sp_video_context.c \
-       sp_winsys.c
+       sp_video_context.c
 
 include ../../Makefile.template
index 3042e556c6417f7b07d5dc055f535afa9e0d0a70..27ab00b036e539eb1e969ec6d6d221214ccf10e1 100644 (file)
@@ -7,6 +7,7 @@ softpipe = env.ConvenienceLibrary(
        source = [
                'sp_fs_exec.c',
                'sp_fs_sse.c',
+               'sp_buffer.c',
                'sp_clear.c',
                'sp_context.c',
                'sp_draw_arrays.c',
@@ -33,8 +34,7 @@ softpipe = env.ConvenienceLibrary(
                'sp_tex_tile_cache.c',
                'sp_texture.c',
                'sp_tile_cache.c',
-               'sp_video_context.c',
-               'sp_winsys.c'
+               'sp_video_context.c'
        ])
 
 Export('softpipe')
diff --git a/src/gallium/drivers/softpipe/sp_buffer.c b/src/gallium/drivers/softpipe/sp_buffer.c
new file mode 100644 (file)
index 0000000..8f39025
--- /dev/null
@@ -0,0 +1,118 @@
+/**************************************************************************
+ *
+ * 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 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 "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "sp_screen.h"
+#include "sp_buffer.h"
+
+
+static void *
+softpipe_buffer_map(struct pipe_screen *screen,
+                    struct pipe_buffer *buf,
+                    unsigned flags)
+{
+   struct softpipe_buffer *softpipe_buf = softpipe_buffer(buf);
+   return softpipe_buf->data;
+}
+
+
+static void
+softpipe_buffer_unmap(struct pipe_screen *screen,
+                      struct pipe_buffer *buf)
+{
+}
+
+
+static void
+softpipe_buffer_destroy(struct pipe_buffer *buf)
+{
+   struct softpipe_buffer *sbuf = softpipe_buffer(buf);
+
+   if (!sbuf->userBuffer)
+      align_free(sbuf->data);
+      
+   FREE(sbuf);
+}
+
+
+static struct pipe_buffer *
+softpipe_buffer_create(struct pipe_screen *screen,
+                       unsigned alignment,
+                       unsigned usage,
+                       unsigned size)
+{
+   struct softpipe_buffer *buffer = CALLOC_STRUCT(softpipe_buffer);
+
+   pipe_reference_init(&buffer->base.reference, 1);
+   buffer->base.screen = screen;
+   buffer->base.alignment = MAX2(alignment, 16);
+   buffer->base.usage = usage;
+   buffer->base.size = size;
+
+   buffer->data = align_malloc(size, alignment);
+
+   return &buffer->base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+softpipe_user_buffer_create(struct pipe_screen *screen,
+                            void *ptr,
+                            unsigned bytes)
+{
+   struct softpipe_buffer *buffer;
+
+   buffer = CALLOC_STRUCT(softpipe_buffer);
+   if(!buffer)
+      return NULL;
+
+   pipe_reference_init(&buffer->base.reference, 1);
+   buffer->base.screen = screen;
+   buffer->base.size = bytes;
+   buffer->userBuffer = TRUE;
+   buffer->data = ptr;
+
+   return &buffer->base;
+}
+
+
+void
+softpipe_init_screen_buffer_funcs(struct pipe_screen *screen)
+{
+   screen->buffer_create = softpipe_buffer_create;
+   screen->user_buffer_create = softpipe_user_buffer_create;
+   screen->buffer_map = softpipe_buffer_map;
+   screen->buffer_unmap = softpipe_buffer_unmap;
+   screen->buffer_destroy = softpipe_buffer_destroy;
+}
diff --git a/src/gallium/drivers/softpipe/sp_buffer.h b/src/gallium/drivers/softpipe/sp_buffer.h
new file mode 100644 (file)
index 0000000..9d8e56a
--- /dev/null
@@ -0,0 +1,55 @@
+/**************************************************************************
+ *
+ * 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 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 SP_BUFFER_H
+#define SP_BUFFER_H
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+
+struct softpipe_buffer
+{
+   struct pipe_buffer base;
+   boolean userBuffer;  /** Is this a user-space buffer? */
+   void *data;
+};
+
+
+/** Cast wrapper */
+static INLINE struct softpipe_buffer *
+softpipe_buffer( struct pipe_buffer *buf )
+{
+   return (struct softpipe_buffer *)buf;
+}
+
+
+void
+softpipe_init_screen_buffer_funcs(struct pipe_screen *screen);
+
+
+#endif /* SP_BUFFER_H */
index ddc35bcd62902def99f2139d4be30885168876de..53eecd1cbf389604143ec708ed80a181ee458f32 100644 (file)
@@ -210,7 +210,7 @@ softpipe_create_context( struct pipe_screen *screen,
    softpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE );
    softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE );
 
-   softpipe->pipe.winsys = screen->winsys;
+   softpipe->pipe.winsys = NULL;
    softpipe->pipe.screen = screen;
    softpipe->pipe.destroy = softpipe_destroy;
    softpipe->pipe.priv = priv;
index b2acc36bf7af2672c58f2b699071872cd960e3de..0899e1145a833550241d68901a75a418b11cb809 100644 (file)
 #include "sp_context.h"
 #include "sp_query.h"
 #include "sp_state.h"
+#include "sp_buffer.h"
 
 #include "draw/draw_context.h"
 
 
 
-static void
-softpipe_map_constant_buffers(struct softpipe_context *sp)
-{
-   struct pipe_winsys *ws = sp->pipe.winsys;
-   uint i;
-
-   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
-      uint j;
-
-      for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
-         if (sp->constants[i][j] && sp->constants[i][j]->size) {
-            sp->mapped_constants[i][j] = ws->buffer_map(ws,
-                                                        sp->constants[i][j],
-                                                        PIPE_BUFFER_USAGE_CPU_READ);
-         }
-      }
-   }
-
-   for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
-      if (sp->constants[PIPE_SHADER_VERTEX][i]) {
-         draw_set_mapped_constant_buffer(sp->draw,
-                                         PIPE_SHADER_VERTEX,
-                                         i,
-                                         sp->mapped_constants[PIPE_SHADER_VERTEX][i],
-                                         sp->constants[PIPE_SHADER_VERTEX][i]->size);
-      }
-      if (sp->constants[PIPE_SHADER_GEOMETRY][i]) {
-         draw_set_mapped_constant_buffer(sp->draw,
-                                         PIPE_SHADER_GEOMETRY,
-                                         i,
-                                         sp->mapped_constants[PIPE_SHADER_GEOMETRY][i],
-                                         sp->constants[PIPE_SHADER_GEOMETRY][i]->size);
-      }
-   }
-}
-
-
-static void
-softpipe_unmap_constant_buffers(struct softpipe_context *sp)
-{
-   struct pipe_winsys *ws = sp->pipe.winsys;
-   uint i;
 
-   /* really need to flush all prims since the vert/frag shaders const buffers
-    * are going away now.
-    */
-   draw_flush(sp->draw);
-
-   for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
-      draw_set_mapped_constant_buffer(sp->draw,
-                                      PIPE_SHADER_VERTEX,
-                                      i,
-                                      NULL,
-                                      0);
-      draw_set_mapped_constant_buffer(sp->draw,
-                                      PIPE_SHADER_GEOMETRY,
-                                      i,
-                                      NULL,
-                                      0);
-   }
-
-   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
-      uint j;
-
-      for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
-         if (sp->constants[i][j] && sp->constants[i][j]->size) {
-            ws->buffer_unmap(ws, sp->constants[i][j]);
-         }
-         sp->mapped_constants[i][j] = NULL;
-      }
-   }
-}
 
 
 /**
@@ -261,25 +191,16 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
    }
 
    softpipe_map_transfers(sp);
-   softpipe_map_constant_buffers(sp);
 
    /* Map vertex buffers */
    for (i = 0; i < sp->num_vertex_buffers; i++) {
-      void *buf;
-
-      buf = pipe_buffer_map(pipe->screen,
-                            sp->vertex_buffer[i].buffer,
-                            PIPE_BUFFER_USAGE_CPU_READ);
+      void *buf = softpipe_buffer(sp->vertex_buffer[i].buffer)->data;
       draw_set_mapped_vertex_buffer(draw, i, buf);
    }
 
    /* Map index buffer, if present */
    if (indexBuffer) {
-      void *mapped_indexes;
-
-      mapped_indexes = pipe_buffer_map(pipe->screen,
-                                       indexBuffer,
-                                       PIPE_BUFFER_USAGE_CPU_READ);
+      void *mapped_indexes = softpipe_buffer(indexBuffer)->data;
       draw_set_mapped_element_buffer_range(draw,
                                            indexSize,
                                            minIndex,
@@ -300,15 +221,18 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
    /* unmap vertex/index buffers - will cause draw module to flush */
    for (i = 0; i < sp->num_vertex_buffers; i++) {
       draw_set_mapped_vertex_buffer(draw, i, NULL);
-      pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer);
    }
    if (indexBuffer) {
       draw_set_mapped_element_buffer(draw, 0, NULL);
-      pipe_buffer_unmap(pipe->screen, indexBuffer);
    }
 
-   /* Note: leave drawing surfaces mapped */
-   softpipe_unmap_constant_buffers(sp);
+   /*
+    * TODO: Flush only when a user vertex/index buffer is present
+    * (or even better, modify draw module to do this
+    * internally when this condition is seen?)
+    */
+   draw_flush(draw);
 
+   /* Note: leave drawing surfaces mapped */
    sp->dirty_render_cache = TRUE;
 }
index 6ec63fe698af8c6c479b838eeb080cd3508c9a19..107631f6b51c3d8a080c0e040da763b77beeddca 100644 (file)
 #include "pipe/p_defines.h"
 #include "pipe/p_screen.h"
 
+#include "state_tracker/sw_winsys.h"
+
 #include "sp_texture.h"
-#include "sp_winsys.h"
 #include "sp_screen.h"
 #include "sp_context.h"
+#include "sp_buffer.h"
 
 
 static const char *
@@ -145,6 +147,8 @@ softpipe_is_format_supported( struct pipe_screen *screen,
                               unsigned tex_usage, 
                               unsigned geom_flags )
 {
+   struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+
    assert(target == PIPE_TEXTURE_1D ||
           target == PIPE_TEXTURE_2D ||
           target == PIPE_TEXTURE_3D ||
@@ -166,15 +170,25 @@ softpipe_is_format_supported( struct pipe_screen *screen,
    case PIPE_FORMAT_NONE:
       return FALSE;
    default:
-      return TRUE;
+      break;
    }
+
+   if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+      if(!winsys->is_displaytarget_format_supported(winsys, format))
+         return FALSE;
+   }
+
+   /* XXX: this is often a lie.  Pull in logic from llvmpipe to fix.
+    */
+   return TRUE;
 }
 
 
 static void
 softpipe_destroy_screen( struct pipe_screen *screen )
 {
-   struct pipe_winsys *winsys = screen->winsys;
+   struct softpipe_screen *sp_screen = softpipe_screen(screen);
+   struct sw_winsys *winsys = sp_screen->winsys;
 
    if(winsys->destroy)
       winsys->destroy(winsys);
@@ -183,21 +197,37 @@ softpipe_destroy_screen( struct pipe_screen *screen )
 }
 
 
+/* This is often overriden by the co-state tracker.
+ */
+static void
+softpipe_flush_frontbuffer(struct pipe_screen *_screen,
+                           struct pipe_surface *surface,
+                           void *context_private)
+{
+   struct softpipe_screen *screen = softpipe_screen(_screen);
+   struct sw_winsys *winsys = screen->winsys;
+   struct softpipe_texture *texture = softpipe_texture(surface->texture);
+
+   assert(texture->dt);
+   if (texture->dt)
+      winsys->displaytarget_display(winsys, texture->dt, context_private);
+}
 
 /**
  * Create a new pipe_screen object
  * Note: we're not presently subclassing pipe_screen (no softpipe_screen).
  */
 struct pipe_screen *
-softpipe_create_screen(struct pipe_winsys *winsys)
+softpipe_create_screen(struct sw_winsys *winsys)
 {
    struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen);
 
    if (!screen)
       return NULL;
 
-   screen->base.winsys = winsys;
+   screen->winsys = winsys;
 
+   screen->base.winsys = NULL;
    screen->base.destroy = softpipe_destroy_screen;
 
    screen->base.get_name = softpipe_get_name;
@@ -206,9 +236,10 @@ softpipe_create_screen(struct pipe_winsys *winsys)
    screen->base.get_paramf = softpipe_get_paramf;
    screen->base.is_format_supported = softpipe_is_format_supported;
    screen->base.context_create = softpipe_create_context;
+   screen->base.flush_frontbuffer = softpipe_flush_frontbuffer;
 
    softpipe_init_screen_texture_funcs(&screen->base);
-   u_simple_screen_init(&screen->base);
+   softpipe_init_screen_buffer_funcs(&screen->base);
 
    return &screen->base;
 }
index 3d4bfd3e840b9c2909bfa01ca4c3ecde5f318bde..4d7d8bada2cdbf9461162c7eb6474441e8b56667 100644 (file)
 #include "pipe/p_defines.h"
 
 
+struct sw_winsys;
 
 struct softpipe_screen {
    struct pipe_screen base;
 
+   struct sw_winsys *winsys;
+
    /* Increments whenever textures are modified.  Contexts can track
     * this.
     */
@@ -55,4 +58,13 @@ softpipe_screen( struct pipe_screen *pipe )
 }
 
 
+
+/**
+ * Create a softpipe screen that uses the
+ * given winsys for allocating buffers.
+ */
+struct pipe_screen *softpipe_create_screen( struct sw_winsys * );
+
+
+
 #endif /* SP_SCREEN_H */
index c88e213751092320e127ff2c9523ddf8b29d9026..cd0e905bc990c6c2fb23d8d046847622d06db0eb 100644 (file)
@@ -28,6 +28,7 @@
 #include "sp_context.h"
 #include "sp_state.h"
 #include "sp_fs.h"
+#include "sp_buffer.h"
 
 #include "pipe/p_defines.h"
 #include "util/u_memory.h"
@@ -163,26 +164,35 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
    FREE( state );
 }
 
-
-
 void
 softpipe_set_constant_buffer(struct pipe_context *pipe,
                              uint shader, uint index,
-                             struct pipe_buffer *buf)
+                             struct pipe_buffer *constants)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
+   unsigned size = constants ? constants->size : 0;
+   const void *data = constants ? softpipe_buffer(constants)->data : NULL;
 
    assert(shader < PIPE_SHADER_TYPES);
-   assert(index < PIPE_MAX_CONSTANT_BUFFERS);
+   assert(index == 0);
+
+   if(softpipe->constants[shader][index] == constants)
+      return;
 
    draw_flush(softpipe->draw);
 
    /* note: reference counting */
-   pipe_buffer_reference(&softpipe->constants[shader][index], buf);
+   pipe_buffer_reference(&softpipe->constants[shader][index], constants);
+
+   if(shader == PIPE_SHADER_VERTEX) {
+      draw_set_mapped_constant_buffer(softpipe->draw, PIPE_SHADER_VERTEX, 0,
+                                      data, size);
+   }
 
    softpipe->dirty |= SP_NEW_CONSTANTS;
 }
 
+
 void *
 softpipe_create_gs_state(struct pipe_context *pipe,
                          const struct pipe_shader_state *templ)
index 32d261b5ffc326b2aad180fbe4497b6c430566b8..9641652da85c7f6b5f6c96bfb0691158fcb61bca 100644 (file)
@@ -40,7 +40,8 @@
 #include "sp_context.h"
 #include "sp_texture.h"
 #include "sp_screen.h"
-#include "sp_winsys.h"
+
+#include "state_tracker/sw_winsys.h"
 
 
 /**
@@ -72,11 +73,9 @@ softpipe_texture_layout(struct pipe_screen *screen,
       depth = u_minify(depth, 1);
    }
 
-   spt->buffer = screen->buffer_create(screen, 32,
-                                       PIPE_BUFFER_USAGE_PIXEL,
-                                       buffer_size);
+   spt->data = align_malloc(buffer_size, 16);
 
-   return spt->buffer != NULL;
+   return spt->data != NULL;
 }
 
 
@@ -87,19 +86,18 @@ static boolean
 softpipe_displaytarget_layout(struct pipe_screen *screen,
                               struct softpipe_texture * spt)
 {
-   unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE |
-                     PIPE_BUFFER_USAGE_GPU_READ_WRITE);
-   unsigned tex_usage = spt->base.tex_usage;
-
-   spt->buffer = screen->surface_buffer_create( screen, 
-                                                spt->base.width0, 
-                                                spt->base.height0,
-                                                spt->base.format,
-                                                usage,
-                                                tex_usage,
-                                                &spt->stride[0]);
-
-   return spt->buffer != NULL;
+   struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+
+   /* Round up the surface size to a multiple of the tile size?
+    */
+   spt->dt = winsys->displaytarget_create(winsys,
+                                          spt->base.format,
+                                          spt->base.width0, 
+                                          spt->base.height0,
+                                          16,
+                                          &spt->stride[0] );
+
+   return spt->dt != NULL;
 }
 
 
@@ -149,37 +147,29 @@ softpipe_texture_blanket(struct pipe_screen * screen,
                          const unsigned *stride,
                          struct pipe_buffer *buffer)
 {
-   struct softpipe_texture *spt;
-   assert(screen);
-
-   /* Only supports one type */
-   if (base->target != PIPE_TEXTURE_2D ||
-       base->last_level != 0 ||
-       base->depth0 != 1) {
-      return NULL;
-   }
-
-   spt = CALLOC_STRUCT(softpipe_texture);
-   if (!spt)
-      return NULL;
-
-   spt->base = *base;
-   pipe_reference_init(&spt->base.reference, 1);
-   spt->base.screen = screen;
-   spt->stride[0] = stride[0];
-
-   pipe_buffer_reference(&spt->buffer, buffer);
-
-   return &spt->base;
+   /* Texture blanket is going away.
+    */
+   debug_printf("softpipe_texture_blanket() not implemented!");
+   return NULL;
 }
 
 
 static void
 softpipe_texture_destroy(struct pipe_texture *pt)
 {
+   struct softpipe_screen *screen = softpipe_screen(pt->screen);
    struct softpipe_texture *spt = softpipe_texture(pt);
 
-   pipe_buffer_reference(&spt->buffer, NULL);
+   if (spt->dt) {
+      /* display target */
+      struct sw_winsys *winsys = screen->winsys;
+      winsys->displaytarget_destroy(winsys, spt->dt);
+   }
+   else {
+      /* regular texture */
+      align_free(spt->data);
+   }
+
    FREE(spt);
 }
 
@@ -359,9 +349,20 @@ softpipe_transfer_map( struct pipe_screen *screen,
    spt = softpipe_texture(transfer->texture);
    format = transfer->texture->format;
 
-   map = pipe_buffer_map(screen, spt->buffer, pipe_transfer_buffer_flags(transfer));
-   if (map == NULL)
-      return NULL;
+   if (spt->dt) {
+      /* display target */
+      struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+
+      map = winsys->displaytarget_map(winsys, spt->dt,
+                                      pipe_transfer_buffer_flags(transfer));
+      if (map == NULL)
+         return NULL;
+   }
+   else {
+      map = spt->data;
+      if (map == NULL)
+         return NULL;
+   }
 
    /* May want to different things here depending on read/write nature
     * of the map:
@@ -393,7 +394,11 @@ softpipe_transfer_unmap(struct pipe_screen *screen,
    assert(transfer->texture);
    spt = softpipe_texture(transfer->texture);
 
-   pipe_buffer_unmap( screen, spt->buffer );
+   if (spt->dt) {
+      /* display target */
+      struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+      winsys->displaytarget_unmap(winsys, spt->dt);
+   }
 
    if (transfer->usage & PIPE_TRANSFER_WRITE) {
       /* Mark the texture as dirty to expire the tile caches. */
@@ -474,24 +479,4 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
 }
 
 
-/**
- * Return pipe_buffer handle and stride for given texture object.
- * XXX used for???
- */
-boolean
-softpipe_get_texture_buffer( struct pipe_texture *texture,
-                             struct pipe_buffer **buf,
-                             unsigned *stride )
-{
-   struct softpipe_texture *tex = (struct softpipe_texture *) texture;
 
-   if (!tex)
-      return FALSE;
-
-   pipe_buffer_reference(buf, tex->buffer);
-
-   if (stride)
-      *stride = tex->stride[0];
-
-   return TRUE;
-}
index 2ef64e1e7c31bec2a582a30379023cf1f37047a8..e8d17ce7daf5362df57d86d598fd8d546c7ad6de 100644 (file)
@@ -45,9 +45,16 @@ struct softpipe_texture
    unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
    unsigned stride[PIPE_MAX_TEXTURE_LEVELS];
 
-   /* The data is held here:
+   /**
+    * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
+    * usage.
+    */
+   struct sw_displaytarget *dt;
+
+   /**
+    * Malloc'ed data for regular textures, or a mapping to dt above.
     */
-   struct pipe_buffer *buffer;
+   void *data;
 
    /* True if texture images are power-of-two in all dimensions:
     */
diff --git a/src/gallium/drivers/softpipe/sp_winsys.c b/src/gallium/drivers/softpipe/sp_winsys.c
deleted file mode 100644 (file)
index 0a6245e..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/**************************************************************************
- * 
- * 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.
- * 
- * 
- **************************************************************************/
-
-/**
- * @file
- * Malloc softpipe winsys. Uses malloc for all memory allocations.
- * 
- * @author Keith Whitwell
- * @author Brian Paul
- * @author Jose Fonseca
- */
-
-
-#include "util/u_simple_screen.h"/* port to just p_screen */
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "util/u_inlines.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "sp_winsys.h"
-
-
-struct st_softpipe_buffer
-{
-   struct pipe_buffer base;
-   boolean userBuffer;  /** Is this a user-space buffer? */
-   void *data;
-   void *mapped;
-};
-
-
-/** Cast wrapper */
-static INLINE struct st_softpipe_buffer *
-st_softpipe_buffer( struct pipe_buffer *buf )
-{
-   return (struct st_softpipe_buffer *)buf;
-}
-
-
-static void *
-st_softpipe_buffer_map(struct pipe_winsys *winsys, 
-                       struct pipe_buffer *buf,
-                       unsigned flags)
-{
-   struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
-   st_softpipe_buf->mapped = st_softpipe_buf->data;
-   return st_softpipe_buf->mapped;
-}
-
-
-static void
-st_softpipe_buffer_unmap(struct pipe_winsys *winsys, 
-                         struct pipe_buffer *buf)
-{
-   struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
-   st_softpipe_buf->mapped = NULL;
-}
-
-
-static void
-st_softpipe_buffer_destroy(struct pipe_buffer *buf)
-{
-   struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf);
-
-   if (oldBuf->data) {
-      if (!oldBuf->userBuffer)
-         align_free(oldBuf->data);
-
-      oldBuf->data = NULL;
-   }
-
-   FREE(oldBuf);
-}
-
-
-static void
-st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys,
-                              struct pipe_surface *surf,
-                              void *context_private)
-{
-}
-
-
-
-static const char *
-st_softpipe_get_name(struct pipe_winsys *winsys)
-{
-   return "softpipe";
-}
-
-
-static struct pipe_buffer *
-st_softpipe_buffer_create(struct pipe_winsys *winsys, 
-                          unsigned alignment, 
-                          unsigned usage,
-                          unsigned size)
-{
-   struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer);
-
-   pipe_reference_init(&buffer->base.reference, 1);
-   buffer->base.alignment = alignment;
-   buffer->base.usage = usage;
-   buffer->base.size = size;
-
-   buffer->data = align_malloc(size, alignment);
-
-   return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-st_softpipe_user_buffer_create(struct pipe_winsys *winsys, 
-                               void *ptr, 
-                               unsigned bytes)
-{
-   struct st_softpipe_buffer *buffer;
-   
-   buffer = CALLOC_STRUCT(st_softpipe_buffer);
-   if(!buffer)
-      return NULL;
-   
-   pipe_reference_init(&buffer->base.reference, 1);
-   buffer->base.size = bytes;
-   buffer->userBuffer = TRUE;
-   buffer->data = ptr;
-
-   return &buffer->base;
-}
-
-
-static struct pipe_buffer *
-st_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
-                                  unsigned width, unsigned height,
-                                  enum pipe_format format,
-                                  unsigned usage,
-                                  unsigned tex_usage,
-                                  unsigned *stride)
-{
-   const unsigned alignment = 64;
-   unsigned nblocksy;
-
-   nblocksy = util_format_get_nblocksy(format, height);
-   *stride = align(util_format_get_stride(format, width), alignment);
-
-   return winsys->buffer_create(winsys, alignment,
-                                usage,
-                                *stride * nblocksy);
-}
-
-
-static void
-st_softpipe_fence_reference(struct pipe_winsys *winsys, 
-                            struct pipe_fence_handle **ptr,
-                            struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-st_softpipe_fence_signalled(struct pipe_winsys *winsys, 
-                            struct pipe_fence_handle *fence,
-                            unsigned flag)
-{
-   return 0;
-}
-
-
-static int
-st_softpipe_fence_finish(struct pipe_winsys *winsys, 
-                         struct pipe_fence_handle *fence,
-                         unsigned flag)
-{
-   return 0;
-}
-
-
-static void
-st_softpipe_destroy(struct pipe_winsys *winsys)
-{
-   FREE(winsys);
-}
-
-
-struct pipe_screen *
-softpipe_create_screen_malloc(void)
-{
-   static struct pipe_winsys *winsys;
-   struct pipe_screen *screen;
-
-   winsys = CALLOC_STRUCT(pipe_winsys);
-   if(!winsys)
-      return NULL;
-
-   winsys->destroy = st_softpipe_destroy;
-   
-   winsys->buffer_create = st_softpipe_buffer_create;
-   winsys->user_buffer_create = st_softpipe_user_buffer_create;
-   winsys->buffer_map = st_softpipe_buffer_map;
-   winsys->buffer_unmap = st_softpipe_buffer_unmap;
-   winsys->buffer_destroy = st_softpipe_buffer_destroy;
-
-   winsys->surface_buffer_create = st_softpipe_surface_buffer_create;
-
-   winsys->fence_reference = st_softpipe_fence_reference;
-   winsys->fence_signalled = st_softpipe_fence_signalled;
-   winsys->fence_finish = st_softpipe_fence_finish;
-
-   winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer;
-   winsys->get_name = st_softpipe_get_name;
-
-   screen = softpipe_create_screen(winsys);
-   if(!screen)
-      st_softpipe_destroy(winsys);
-
-   return screen;
-}
diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h
deleted file mode 100644 (file)
index 6e3920c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/* This is the interface that softpipe requires any window system
- * hosting it to implement.  This is the only include file in softpipe
- * which is public.
- */
-
-
-#ifndef SP_WINSYS_H
-#define SP_WINSYS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "pipe/p_defines.h"
-
-struct pipe_screen;
-struct pipe_winsys;
-struct pipe_context;
-struct pipe_texture;
-struct pipe_buffer;
-
-
-
-/**
- * Create a softpipe screen that uses the
- * given winsys for allocating buffers.
- */
-struct pipe_screen *softpipe_create_screen( struct pipe_winsys * );
-
-/**
- * Create a softpipe screen that uses
- * regular malloc to create all its buffers.
- */
-struct pipe_screen *softpipe_create_screen_malloc(void);
-
-boolean
-softpipe_get_texture_buffer( struct pipe_texture *texture,
-                             struct pipe_buffer **buf,
-                             unsigned *stride );
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* SP_WINSYS_H */
diff --git a/src/gallium/include/state_tracker/sw_winsys.h b/src/gallium/include/state_tracker/sw_winsys.h
new file mode 100644 (file)
index 0000000..719c3f3
--- /dev/null
@@ -0,0 +1,121 @@
+/**************************************************************************
+ * 
+ * Copyright 2007-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 above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/**
+ * @file
+ * Software rasterizer winsys.
+ */
+
+
+#ifndef SW_WINSYS_H
+#define SW_WINSYS_H
+
+
+#include "pipe/p_compiler.h" /* for boolean */
+#include "pipe/p_format.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct pipe_screen;
+struct pipe_context;
+
+
+/**
+ * Opaque pointer.
+ */
+struct sw_displaytarget;
+
+
+/**
+ * This is the interface that sw expects any window system
+ * hosting it to implement.
+ * 
+ * sw is for the most part a self sufficient driver. The only thing it
+ * does not know is how to display a surface.
+ */
+struct sw_winsys
+{
+   void 
+   (*destroy)( struct sw_winsys *ws );
+
+   boolean
+   (*is_displaytarget_format_supported)( struct sw_winsys *ws,
+                                         enum pipe_format format );
+   
+   /**
+    * Allocate storage for a render target.
+    * 
+    * Often surfaces which are meant to be blitted to the front screen (i.e.,
+    * display targets) must be allocated with special characteristics, memory 
+    * pools, or obtained directly from the windowing system.
+    *  
+    * This callback is invoked by the pipe_screen when creating a texture marked
+    * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying 
+    * storage.
+    */
+   struct sw_displaytarget *
+   (*displaytarget_create)( struct sw_winsys *ws,
+                            enum pipe_format format,
+                            unsigned width, unsigned height,
+                            unsigned alignment,
+                            unsigned *stride );
+
+   void *
+   (*displaytarget_map)( struct sw_winsys *ws, 
+                         struct sw_displaytarget *dt,
+                         unsigned flags );
+
+   void
+   (*displaytarget_unmap)( struct sw_winsys *ws,
+                           struct sw_displaytarget *dt );
+
+   /**
+    * @sa pipe_screen:flush_frontbuffer.
+    *
+    * This call will likely become asynchronous eventually.
+    */
+   void
+   (*displaytarget_display)( struct sw_winsys *ws, 
+                             struct sw_displaytarget *dt,
+                             void *context_private );
+
+   void 
+   (*displaytarget_destroy)( struct sw_winsys *ws, 
+                             struct sw_displaytarget *dt );
+};
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SW_WINSYS_H */
index 4cbc86f3311212596d5e00c0c551efbaefe4e254..4b32aa27e17a9c1c4ea47ceed3c9c78bc26feaae 100644 (file)
@@ -18,7 +18,7 @@ if env['platform'] == 'windows':
         'ws2_32',
     ])
 
-    sources = []
+    sources = ['gdi_sw_winsys.c']
     drivers = []
 
     if 'softpipe' in env['drivers']:
index a9fa03b8e57ac73b05d9e38cf97e67aace73fbf6..3d317c70dda513be49536dc7e1861ac9540430c5 100644 (file)
 
 #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 "llvmpipe/lp_winsys.h"
+#include "gdi_winsys.h"
 #include "llvmpipe/lp_texture.h"
-#include "stw_winsys.h"
-
-
-struct gdi_llvmpipe_displaytarget
-{
-   enum pipe_format format;
-   unsigned width;
-   unsigned height;
-   unsigned stride;
-
-   unsigned size;
-
-   void *data;
-
-   BITMAPINFO bmi;
-};
-
-
-/** Cast wrapper */
-static INLINE struct gdi_llvmpipe_displaytarget *
-gdi_llvmpipe_displaytarget( struct llvmpipe_displaytarget *buf )
-{
-   return (struct gdi_llvmpipe_displaytarget *)buf;
-}
-
-
-static boolean
-gdi_llvmpipe_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
-                                                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_llvmpipe_displaytarget_map(struct llvmpipe_winsys *ws,
-                               struct llvmpipe_displaytarget *dt,
-                               unsigned flags )
-{
-   struct gdi_llvmpipe_displaytarget *gdt = gdi_llvmpipe_displaytarget(dt);
-
-   return gdt->data;
-}
-
-
-static void
-gdi_llvmpipe_displaytarget_unmap(struct llvmpipe_winsys *ws,
-                                 struct llvmpipe_displaytarget *dt )
-{
-
-}
-
-
-static void
-gdi_llvmpipe_displaytarget_destroy(struct llvmpipe_winsys *winsys,
-                                   struct llvmpipe_displaytarget *dt)
-{
-   struct gdi_llvmpipe_displaytarget *gdt = gdi_llvmpipe_displaytarget(dt);
-
-   align_free(gdt->data);
-   FREE(gdt);
-}
-
-
-static struct llvmpipe_displaytarget *
-gdi_llvmpipe_displaytarget_create(struct llvmpipe_winsys *winsys,
-                                  enum pipe_format format,
-                                  unsigned width, unsigned height,
-                                  unsigned alignment,
-                                  unsigned *stride)
-{
-   struct gdi_llvmpipe_displaytarget *gdt;
-   unsigned cpp;
-   unsigned bpp;
-   
-   gdt = CALLOC_STRUCT(gdi_llvmpipe_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 llvmpipe_displaytarget *)gdt;
-
-no_data:
-   FREE(gdt);
-no_gdt:
-   return NULL;
-}
-
-
-static void
-gdi_llvmpipe_displaytarget_display(struct llvmpipe_winsys *winsys, 
-                                   struct llvmpipe_displaytarget *dt,
-                                   void *context_private)
-{
-   assert(0);
-}
-
-
-static void
-gdi_llvmpipe_destroy(struct llvmpipe_winsys *winsys)
-{
-   FREE(winsys);
-}
 
 
 static struct pipe_screen *
@@ -191,18 +46,10 @@ gdi_llvmpipe_screen_create(void)
    static struct llvmpipe_winsys *winsys;
    struct pipe_screen *screen;
 
-   winsys = CALLOC_STRUCT(llvmpipe_winsys);
+   winsys = gdi_create_sw_winsys();
    if(!winsys)
       goto no_winsys;
 
-   winsys->destroy = gdi_llvmpipe_destroy;
-   winsys->is_displaytarget_format_supported = gdi_llvmpipe_is_displaytarget_format_supported;
-   winsys->displaytarget_create = gdi_llvmpipe_displaytarget_create;
-   winsys->displaytarget_map = gdi_llvmpipe_displaytarget_map;
-   winsys->displaytarget_unmap = gdi_llvmpipe_displaytarget_unmap;
-   winsys->displaytarget_display = gdi_llvmpipe_displaytarget_display;
-   winsys->displaytarget_destroy = gdi_llvmpipe_displaytarget_destroy;
-
    screen = llvmpipe_create_screen(winsys);
    if(!screen)
       goto no_screen;
index 71360e55aac78a2dbc3315520d7bf156084fff3b..56e84fd06629a47760e91d80e7c5d48805b071d9 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  *
- * Copyright 2008 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * Copyright 2009 VMware, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
 
 /**
  * @file
- * Softpipe support.
+ * LLVMpipe support.
  *
- * @author Keith Whitwell
- * @author Brian Paul
- * @author Jose Fonseca
+ * @author Jose Fonseca <jfonseca@vmware.com>
  */
 
 
 #include <windows.h>
 
-#include "util/u_simple_screen.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "softpipe/sp_winsys.h"
+#include "gdi_winsys.h"
 #include "softpipe/sp_texture.h"
-#include "stw_winsys.h"
-
-
-struct gdi_softpipe_buffer
-{
-   struct pipe_buffer base;
-   boolean userBuffer;  /** Is this a user-space buffer? */
-   void *data;
-   void *mapped;
-};
-
-
-/** Cast wrapper */
-static INLINE struct gdi_softpipe_buffer *
-gdi_softpipe_buffer( struct pipe_buffer *buf )
-{
-   return (struct gdi_softpipe_buffer *)buf;
-}
-
-
-static void *
-gdi_softpipe_buffer_map(struct pipe_winsys *winsys,
-                        struct pipe_buffer *buf,
-                        unsigned flags)
-{
-   struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf);
-   gdi_softpipe_buf->mapped = gdi_softpipe_buf->data;
-   return gdi_softpipe_buf->mapped;
-}
-
-
-static void
-gdi_softpipe_buffer_unmap(struct pipe_winsys *winsys,
-                          struct pipe_buffer *buf)
-{
-   struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf);
-   gdi_softpipe_buf->mapped = NULL;
-}
-
-
-static void
-gdi_softpipe_buffer_destroy(struct pipe_buffer *buf)
-{
-   struct gdi_softpipe_buffer *oldBuf = gdi_softpipe_buffer(buf);
-
-   if (oldBuf->data) {
-      if (!oldBuf->userBuffer)
-         align_free(oldBuf->data);
-
-      oldBuf->data = NULL;
-   }
-
-   FREE(oldBuf);
-}
-
-
-static const char *
-gdi_softpipe_get_name(struct pipe_winsys *winsys)
-{
-   return "softpipe";
-}
-
-
-static struct pipe_buffer *
-gdi_softpipe_buffer_create(struct pipe_winsys *winsys,
-                           unsigned alignment,
-                           unsigned usage,
-                           unsigned size)
-{
-   struct gdi_softpipe_buffer *buffer = CALLOC_STRUCT(gdi_softpipe_buffer);
-
-   pipe_reference_init(&buffer->base.reference, 1);
-   buffer->base.alignment = alignment;
-   buffer->base.usage = usage;
-   buffer->base.size = size;
-
-   buffer->data = align_malloc(size, alignment);
-
-   return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-gdi_softpipe_user_buffer_create(struct pipe_winsys *winsys,
-                               void *ptr,
-                               unsigned bytes)
-{
-   struct gdi_softpipe_buffer *buffer;
-
-   buffer = CALLOC_STRUCT(gdi_softpipe_buffer);
-   if(!buffer)
-      return NULL;
-
-   pipe_reference_init(&buffer->base.reference, 1);
-   buffer->base.size = bytes;
-   buffer->userBuffer = TRUE;
-   buffer->data = ptr;
-
-   return &buffer->base;
-}
-
-
-static struct pipe_buffer *
-gdi_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
-                                   unsigned width, unsigned height,
-                                   enum pipe_format format,
-                                   unsigned usage,
-                                   unsigned tex_usage,
-                                   unsigned *stride)
-{
-   const unsigned alignment = 64;
-   unsigned nblocksy;
-
-   nblocksy = util_format_get_nblocksy(format, height);
-   *stride = align(util_format_get_stride(format, width), alignment);
-
-   return winsys->buffer_create(winsys, alignment,
-                                usage,
-                                *stride * nblocksy);
-}
-
-
-static void
-gdi_softpipe_dummy_flush_frontbuffer(struct pipe_winsys *winsys,
-                                     struct pipe_surface *surface,
-                                     void *context_private)
-{
-   assert(0);
-}
-
-
-static void
-gdi_softpipe_fence_reference(struct pipe_winsys *winsys,
-                             struct pipe_fence_handle **ptr,
-                             struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-gdi_softpipe_fence_signalled(struct pipe_winsys *winsys,
-                             struct pipe_fence_handle *fence,
-                             unsigned flag)
-{
-   return 0;
-}
-
-
-static int
-gdi_softpipe_fence_finish(struct pipe_winsys *winsys,
-                          struct pipe_fence_handle *fence,
-                          unsigned flag)
-{
-   return 0;
-}
-
-
-static void
-gdi_softpipe_destroy(struct pipe_winsys *winsys)
-{
-   FREE(winsys);
-}
 
 
 static struct pipe_screen *
 gdi_softpipe_screen_create(void)
 {
-   static struct pipe_winsys *winsys;
+   static struct softpipe_winsys *winsys;
    struct pipe_screen *screen;
 
-   winsys = CALLOC_STRUCT(pipe_winsys);
+   winsys = gdi_create_sw_winsys();
    if(!winsys)
-      return NULL;
-
-   winsys->destroy = gdi_softpipe_destroy;
-
-   winsys->buffer_create = gdi_softpipe_buffer_create;
-   winsys->user_buffer_create = gdi_softpipe_user_buffer_create;
-   winsys->buffer_map = gdi_softpipe_buffer_map;
-   winsys->buffer_unmap = gdi_softpipe_buffer_unmap;
-   winsys->buffer_destroy = gdi_softpipe_buffer_destroy;
-
-   winsys->surface_buffer_create = gdi_softpipe_surface_buffer_create;
-
-   winsys->fence_reference = gdi_softpipe_fence_reference;
-   winsys->fence_signalled = gdi_softpipe_fence_signalled;
-   winsys->fence_finish = gdi_softpipe_fence_finish;
-
-   winsys->flush_frontbuffer = gdi_softpipe_dummy_flush_frontbuffer;
-   winsys->get_name = gdi_softpipe_get_name;
+      goto no_winsys;
 
    screen = softpipe_create_screen(winsys);
    if(!screen)
-      gdi_softpipe_destroy(winsys);
+      goto no_screen;
 
    return screen;
+   
+no_screen:
+   FREE(winsys);
+no_winsys:
+   return NULL;
 }
 
 
+
+
 static void
 gdi_softpipe_present(struct pipe_screen *screen,
                      struct pipe_surface *surface,
                      HDC hDC)
 {
     struct softpipe_texture *texture;
-    struct gdi_softpipe_buffer *buffer;
-    BITMAPINFO bmi;
+    struct gdi_softpipe_displaytarget *gdt;
 
     texture = softpipe_texture(surface->texture);
-                                               
-    buffer = gdi_softpipe_buffer(texture->buffer);
-
-    memset(&bmi, 0, sizeof(BITMAPINFO));
-    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-    bmi.bmiHeader.biWidth = texture->stride[surface->level] / util_format_get_blocksize(surface->format);
-    bmi.bmiHeader.biHeight= -(long)surface->height;
-    bmi.bmiHeader.biPlanes = 1;
-    bmi.bmiHeader.biBitCount = util_format_get_blocksizebits(surface->format);
-    bmi.bmiHeader.biCompression = BI_RGB;
-    bmi.bmiHeader.biSizeImage = 0;
-    bmi.bmiHeader.biXPelsPerMeter = 0;
-    bmi.bmiHeader.biYPelsPerMeter = 0;
-    bmi.bmiHeader.biClrUsed = 0;
-    bmi.bmiHeader.biClrImportant = 0;
+    gdt = gdi_softpipe_displaytarget(texture->dt);
 
     StretchDIBits(hDC,
-                  0, 0, surface->width, surface->height,
-                  0, 0, surface->width, surface->height,
-                  buffer->data, &bmi, 0, SRCCOPY);
+                  0, 0, gdt->width, gdt->height,
+                  0, 0, gdt->width, gdt->height,
+                  gdt->data, &gdt->bmi, 0, SRCCOPY);
 }
 
 
index 824c666ae30c74da903fc99ff80282f08a8994d4..129300423a6a22304a9dcc640913d822710a1792 100644 (file)
@@ -29,6 +29,7 @@ DEFINES += \
 XLIB_WINSYS_SOURCES = \
        xlib.c \
        xlib_cell.c \
+       xlib_sw_winsys.c \
        xlib_llvmpipe.c \
        xlib_softpipe.c
 
index 8c9d318af2b91cab14ef3d0990681323ccb7580e..92e508ee50c9b8ad3c420a4d49d62f40313de7e1 100644 (file)
@@ -36,7 +36,7 @@ drivers = [trace]
     
 if 'softpipe' in env['drivers']:
     env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
-    sources += ['xlib_softpipe.c']
+    sources += ['xlib_softpipe.c', 'xlib_sw_winsys.c']
     drivers += [softpipe]
 
 if 'llvmpipe' in env['drivers']:
@@ -44,7 +44,7 @@ if 'llvmpipe' in env['drivers']:
     if 'LLVM_VERSION' in env:
         env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
         env.Tool('udis86')
-        sources += ['xlib_llvmpipe.c']
+        sources += ['xlib_llvmpipe.c', 'xlib_sw_winsys.c']
         drivers += [llvmpipe]
     
 if 'cell' in env['drivers']:
index 67617a470d632dbce7827a8941c897d19c4ed9e3..9b91c980d15139a528c47e330326bbbc11b0494c 100644 (file)
@@ -33,9 +33,7 @@
 
 #include "xlib.h"
 #include "xm_winsys.h"
-
-#include <stdlib.h>
-#include <assert.h>
+#include "util/u_debug.h"
 
 /* Todo, replace all this with callback-structs provided by the
  * individual implementations.
index 8e091d0c0842043b8a033564e5a0395108c348df..7f9f910b88d36f1786f6f45c87e0c1c139142d06 100644 (file)
@@ -9,5 +9,12 @@ extern struct xm_driver xlib_softpipe_driver;
 extern struct xm_driver xlib_llvmpipe_driver;
 extern struct xm_driver xlib_cell_driver;
 
+/* Internal:
+ */
+struct sw_winsys;
+struct sw_displaytarget;
+struct sw_winsys *xlib_create_sw_winsys( void );
+void xlib_sw_display(struct xmesa_buffer *xm_buffer,
+                     struct sw_displaytarget *dt);
 
 #endif
index 6cebd4c2012762c0a2572caf0fbf7b6734d6e20f..9929ba52e731d3951fc6a4ba99ab595bc9442ae0 100644 (file)
  */
 
 
-#if defined(GALLIUM_LLVMPIPE)
-
-#include "xm_api.h"
 
-#undef ASSERT
-#undef Elements
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "llvmpipe/lp_winsys.h"
-#include "llvmpipe/lp_texture.h"
 
 #include "xlib.h"
 
-/**
- * Subclass of pipe_buffer for Xlib winsys.
- * Low-level OS/window system memory buffer
- */
-struct xm_displaytarget
-{
-   enum pipe_format format;
-   unsigned width;
-   unsigned height;
-   unsigned stride;
-
-   void *data;
-   void *mapped;
-
-   XImage *tempImage;
-#ifdef USE_XSHM
-   int shm;
-   XShmSegmentInfo shminfo;
-#endif
-};
-
-
-/**
- * Subclass of llvmpipe_winsys for Xlib winsys
- */
-struct xmesa_llvmpipe_winsys
-{
-   struct llvmpipe_winsys base;
-/*   struct xmesa_visual *xm_visual; */
-};
-
-
-
-/** Cast wrapper */
-static INLINE struct xm_displaytarget *
-xm_displaytarget( struct llvmpipe_displaytarget *dt )
-{
-   return (struct xm_displaytarget *)dt;
-}
-
-
-/**
- * X Shared Memory Image extension code
- */
-
-#ifdef USE_XSHM
-
-static volatile int mesaXErrorFlag = 0;
-
-/**
- * Catches potential Xlib errors.
- */
-static int
-mesaHandleXError(Display *dpy, XErrorEvent *event)
-{
-   (void) dpy;
-   (void) event;
-   mesaXErrorFlag = 1;
-   return 0;
-}
-
-
-static char *alloc_shm(struct xm_displaytarget *buf, unsigned size)
-{
-   XShmSegmentInfo *const shminfo = & buf->shminfo;
-
-   shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
-   if (shminfo->shmid < 0) {
-      return NULL;
-   }
-
-   shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
-   if (shminfo->shmaddr == (char *) -1) {
-      shmctl(shminfo->shmid, IPC_RMID, 0);
-      return NULL;
-   }
-
-   shminfo->readOnly = False;
-   return shminfo->shmaddr;
-}
-
-
-/**
- * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
- */
-static void
-alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
-                 struct xmesa_buffer *xmb,
-                 unsigned width, unsigned height)
-{
-   /*
-    * We have to do a _lot_ of error checking here to be sure we can
-    * really use the XSHM extension.  It seems different servers trigger
-    * errors at different points if the extension won't work.  Therefore
-    * we have to be very careful...
-    */
-   int (*old_handler)(Display *, XErrorEvent *);
-
-   xm_buffer->tempImage = XShmCreateImage(xmb->xm_visual->display,
-                                  xmb->xm_visual->visinfo->visual,
-                                  xmb->xm_visual->visinfo->depth,
-                                  ZPixmap,
-                                  NULL,
-                                  &xm_buffer->shminfo,
-                                  width, height);
-   if (xm_buffer->tempImage == NULL) {
-      xm_buffer->shm = 0;
-      return;
-   }
-
-
-   mesaXErrorFlag = 0;
-   old_handler = XSetErrorHandler(mesaHandleXError);
-   /* This may trigger the X protocol error we're ready to catch: */
-   XShmAttach(xmb->xm_visual->display, &xm_buffer->shminfo);
-   XSync(xmb->xm_visual->display, False);
-
-   if (mesaXErrorFlag) {
-      /* we are on a remote display, this error is normal, don't print it */
-      XFlush(xmb->xm_visual->display);
-      mesaXErrorFlag = 0;
-      XDestroyImage(xm_buffer->tempImage);
-      xm_buffer->tempImage = NULL;
-      xm_buffer->shm = 0;
-      (void) XSetErrorHandler(old_handler);
-      return;
-   }
-
-   xm_buffer->shm = 1;
-}
-
-#endif /* USE_XSHM */
-
-static boolean
-xm_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
-                                      enum pipe_format format )
-{
-   /* TODO: check visuals or other sensible thing here */
-   return TRUE;
-}
-
-
-static void *
-xm_displaytarget_map(struct llvmpipe_winsys *ws,
-                     struct llvmpipe_displaytarget *dt,
-                     unsigned flags)
-{
-   struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
-   xm_dt->mapped = xm_dt->data;
-   return xm_dt->mapped;
-}
-
-static void
-xm_displaytarget_unmap(struct llvmpipe_winsys *ws,
-                       struct llvmpipe_displaytarget *dt)
-{
-   struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
-   xm_dt->mapped = NULL;
-}
-
-static void
-xm_displaytarget_destroy(struct llvmpipe_winsys *ws,
-                         struct llvmpipe_displaytarget *dt)
-{
-   struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
-
-   if (xm_dt->data) {
-#ifdef USE_XSHM
-      if (xm_dt->shminfo.shmid >= 0) {
-         shmdt(xm_dt->shminfo.shmaddr);
-         shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0);
-         
-         xm_dt->shminfo.shmid = -1;
-         xm_dt->shminfo.shmaddr = (char *) -1;
-      }
-      else
-#endif
-         FREE(xm_dt->data);
-   }
-
-   FREE(xm_dt);
-}
-
-
-/**
- * Display/copy the image in the surface into the X window specified
- * by the XMesaBuffer.
- */
-static void
-xm_llvmpipe_display(struct xmesa_buffer *xm_buffer,
-                    struct llvmpipe_displaytarget *dt)
-{
-   XImage *ximage;
-   struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
-   static boolean no_swap = 0;
-   static boolean firsttime = 1;
-
-   if (firsttime) {
-      no_swap = getenv("SP_NO_RAST") != NULL;
-      firsttime = 0;
-   }
-
-   if (no_swap)
-      return;
-
-#ifdef USE_XSHM
-   if (xm_dt->shm)
-   {
-      if (xm_dt->tempImage == NULL)
-      {
-         assert(util_format_get_blockwidth(xm_dt->format) == 1);
-         assert(util_format_get_blockheight(xm_dt->format) == 1);
-         alloc_shm_ximage(xm_dt, xm_buffer,
-                          xm_dt->stride / util_format_get_blocksize(xm_dt->format),
-                          xm_dt->height);
-      }
-
-      ximage = xm_dt->tempImage;
-      ximage->data = xm_dt->data;
-
-      /* _debug_printf("XSHM\n"); */
-      XShmPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
-                   ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False);
-   }
-   else
-#endif
-   {
-      /* display image in Window */
-      ximage = xm_dt->tempImage;
-      ximage->data = xm_dt->data;
-
-      /* check that the XImage has been previously initialized */
-      assert(ximage->format);
-      assert(ximage->bitmap_unit);
-
-      /* update XImage's fields */
-      ximage->width = xm_dt->width;
-      ximage->height = xm_dt->height;
-      ximage->bytes_per_line = xm_dt->stride;
-
-      /* _debug_printf("XPUT\n"); */
-      XPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
-                ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height);
-   }
-}
-
-/**
- * Display/copy the image in the surface into the X window specified
- * by the XMesaBuffer.
- */
-static void
-xm_displaytarget_display(struct llvmpipe_winsys *ws,
-                         struct llvmpipe_displaytarget *dt,
-                         void *context_private)
-{
-   XMesaContext xmctx = (XMesaContext) context_private;
-   struct xmesa_buffer *xm_buffer = xmctx->xm_buffer;
-   xm_llvmpipe_display(xm_buffer, dt);
-}
-
 
-static struct llvmpipe_displaytarget *
-xm_displaytarget_create(struct llvmpipe_winsys *winsys,
-                        enum pipe_format format,
-                        unsigned width, unsigned height,
-                        unsigned alignment,
-                        unsigned *stride)
-{
-   struct xm_displaytarget *xm_dt = CALLOC_STRUCT(xm_displaytarget);
-   unsigned nblocksy, size;
-
-   xm_dt = CALLOC_STRUCT(xm_displaytarget);
-   if(!xm_dt)
-      goto no_xm_dt;
-
-   xm_dt->format = format;
-   xm_dt->width = width;
-   xm_dt->height = height;
-
-   nblocksy = util_format_get_nblocksy(format, height);
-   xm_dt->stride = align(util_format_get_stride(format, width), alignment);
-   size = xm_dt->stride * nblocksy;
-
-#ifdef USE_XSHM
-   if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
-   {
-      xm_dt->shminfo.shmid = -1;
-      xm_dt->shminfo.shmaddr = (char *) -1;
-      xm_dt->shm = TRUE;
-         
-      xm_dt->data = alloc_shm(xm_dt, size);
-      if(!xm_dt->data)
-         goto no_data;
-   }
-#endif
-
-   if(!xm_dt->data) {
-      xm_dt->data = align_malloc(size, alignment);
-      if(!xm_dt->data)
-         goto no_data;
-   }
-
-   *stride = xm_dt->stride;
-   return (struct llvmpipe_displaytarget *)xm_dt;
-
-no_data:
-   FREE(xm_dt);
-no_xm_dt:
-   return NULL;
-}
-
-
-static void
-xm_destroy( struct llvmpipe_winsys *ws )
-{
-   FREE(ws);
-}
-
-
-static struct llvmpipe_winsys *
-xlib_create_llvmpipe_winsys( void )
-{
-   struct xmesa_llvmpipe_winsys *ws;
-
-   ws = CALLOC_STRUCT(xmesa_llvmpipe_winsys);
-   if (!ws)
-      return NULL;
-
-   ws->base.destroy = xm_destroy;
-
-   ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
-
-   ws->base.displaytarget_create = xm_displaytarget_create;
-   ws->base.displaytarget_map = xm_displaytarget_map;
-   ws->base.displaytarget_unmap = xm_displaytarget_unmap;
-   ws->base.displaytarget_destroy = xm_displaytarget_destroy;
-
-   ws->base.displaytarget_display = xm_displaytarget_display;
-
-   return &ws->base;
-}
+#if defined(GALLIUM_LLVMPIPE)
 
+#include "llvmpipe/lp_texture.h"
+#include "llvmpipe/lp_winsys.h"
+#include "state_tracker/sw_winsys.h"
 
 static struct pipe_screen *
 xlib_create_llvmpipe_screen( void )
@@ -401,7 +50,7 @@ xlib_create_llvmpipe_screen( void )
    struct llvmpipe_winsys *winsys;
    struct pipe_screen *screen;
 
-   winsys = xlib_create_llvmpipe_winsys();
+   winsys = xlib_create_sw_winsys();
    if (winsys == NULL)
       return NULL;
 
@@ -427,7 +76,7 @@ xlib_llvmpipe_display_surface(struct xmesa_buffer *xm_buffer,
 
    assert(texture->dt);
    if (texture->dt)
-      xm_llvmpipe_display(xm_buffer, texture->dt);
+      xlib_sw_display(xm_buffer, texture->dt);
 }
 
 
index 716338aef47f76b943a946b603cd6649f6fa26ad..df93de551cc79286a23c4705cf9c833f84439954 100644 (file)
  * 
  **************************************************************************/
 
-/*
- * Authors:
- *   Keith Whitwell
- *   Brian Paul
- */
-
-
-#include "xm_api.h"
-
-#undef ASSERT
-#undef Elements
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "softpipe/sp_winsys.h"
-#include "softpipe/sp_texture.h"
 
 #include "xlib.h"
-
-/**
- * Subclass of pipe_buffer for Xlib winsys.
- * Low-level OS/window system memory buffer
- */
-struct xm_buffer
-{
-   struct pipe_buffer base;
-   boolean userBuffer;  /** Is this a user-space buffer? */
-   void *data;
-   void *mapped;
-
-   XImage *tempImage;
-#ifdef USE_XSHM
-   boolean shm;         /** Is this a shared memory buffer? */
-   XShmSegmentInfo shminfo;
-#endif
-};
-
-
-/**
- * Subclass of pipe_winsys for Xlib winsys
- */
-struct xmesa_pipe_winsys
-{
-   struct pipe_winsys base;
-/*   struct xmesa_visual *xm_visual; */
-};
-
-
-
-/** Cast wrapper */
-static INLINE struct xm_buffer *
-xm_buffer( struct pipe_buffer *buf )
-{
-   return (struct xm_buffer *)buf;
-}
-
-
-/**
- * X Shared Memory Image extension code
- */
-
-#ifdef USE_XSHM
-
-static volatile int mesaXErrorFlag = 0;
-
-/**
- * Catches potential Xlib errors.
- */
-static int
-mesaHandleXError(Display *dpy, XErrorEvent *event)
-{
-   (void) dpy;
-   (void) event;
-   mesaXErrorFlag = 1;
-   return 0;
-}
-
-
-static char *alloc_shm(struct xm_buffer *buf, unsigned size)
-{
-   XShmSegmentInfo *const shminfo = & buf->shminfo;
-
-   shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
-   if (shminfo->shmid < 0) {
-      return NULL;
-   }
-
-   shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
-   if (shminfo->shmaddr == (char *) -1) {
-      shmctl(shminfo->shmid, IPC_RMID, 0);
-      return NULL;
-   }
-
-   shminfo->readOnly = False;
-   return shminfo->shmaddr;
-}
-
-
-/**
- * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
- */
-static void
-alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb,
-                 unsigned width, unsigned height)
-{
-   /*
-    * We have to do a _lot_ of error checking here to be sure we can
-    * really use the XSHM extension.  It seems different servers trigger
-    * errors at different points if the extension won't work.  Therefore
-    * we have to be very careful...
-    */
-   int (*old_handler)(Display *, XErrorEvent *);
-
-   b->tempImage = XShmCreateImage(xmb->xm_visual->display,
-                                  xmb->xm_visual->visinfo->visual,
-                                  xmb->xm_visual->visinfo->depth,
-                                  ZPixmap,
-                                  NULL,
-                                  &b->shminfo,
-                                  width, height);
-   if (b->tempImage == NULL) {
-      b->shm = FALSE;
-      return;
-   }
-
-
-   mesaXErrorFlag = 0;
-   old_handler = XSetErrorHandler(mesaHandleXError);
-   /* This may trigger the X protocol error we're ready to catch: */
-   XShmAttach(xmb->xm_visual->display, &b->shminfo);
-   XSync(xmb->xm_visual->display, False);
-
-   if (mesaXErrorFlag) {
-      /* we are on a remote display, this error is normal, don't print it */
-      XFlush(xmb->xm_visual->display);
-      mesaXErrorFlag = 0;
-      XDestroyImage(b->tempImage);
-      b->tempImage = NULL;
-      b->shm = FALSE;
-      (void) XSetErrorHandler(old_handler);
-      return;
-   }
-
-   b->shm = TRUE;
-}
-
-#endif /* USE_XSHM */
-
-
-
-/* Most callbacks map direcly onto dri_bufmgr operations:
- */
-static void *
-xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
-              unsigned flags)
-{
-   struct xm_buffer *xm_buf = xm_buffer(buf);
-   xm_buf->mapped = xm_buf->data;
-   return xm_buf->mapped;
-}
-
-static void
-xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
-   struct xm_buffer *xm_buf = xm_buffer(buf);
-   xm_buf->mapped = NULL;
-}
-
-static void
-xm_buffer_destroy(struct pipe_buffer *buf)
-{
-   struct xm_buffer *oldBuf = xm_buffer(buf);
-
-   /*
-    * Note oldBuf->data may point to one of three things:
-    * 1. XShm shared memory image data
-    * 2. User-provided (wrapped) memory, see xm_user_buffer_create()
-    * 3. Regular, malloc'd memory
-    * We need to be careful with freeing that data now.
-    */
-
-   if (oldBuf->data) {
-#ifdef USE_XSHM
-      if (oldBuf->shminfo.shmid >= 0) {
-         shmdt(oldBuf->shminfo.shmaddr);
-         shmctl(oldBuf->shminfo.shmid, IPC_RMID, 0);
-         
-         oldBuf->shminfo.shmid = -1;
-         oldBuf->shminfo.shmaddr = (char *) -1;
-      }
-
-      if (oldBuf->shm) {
-         oldBuf->data = NULL;
-      }
-
-      if (oldBuf->tempImage) {
-         XDestroyImage(oldBuf->tempImage);
-         oldBuf->tempImage = NULL;
-      }
-#endif
-
-      if (oldBuf->data && !oldBuf->userBuffer) {
-         /* this was regular malloc'd memory */
-         align_free(oldBuf->data);
-      }
-
-      oldBuf->data = NULL;
-   }
-
-   free(oldBuf);
-}
-
-
-/**
- * Display/copy the image in the surface into the X window specified
- * by the XMesaBuffer.
- */
-static void
-xlib_softpipe_display_surface(struct xmesa_buffer *b,
-                              struct pipe_surface *surf)
-{
-   XImage *ximage;
-   struct softpipe_texture *spt = softpipe_texture(surf->texture);
-   struct xm_buffer *xm_buf = xm_buffer(spt->buffer);
-   static boolean no_swap = 0;
-   static boolean firsttime = 1;
-
-   if (firsttime) {
-      no_swap = getenv("SP_NO_RAST") != NULL;
-      firsttime = 0;
-   }
-
-   if (no_swap)
-      return;
-
-#ifdef USE_XSHM
-   if (xm_buf->shm)
-   {
-      if (xm_buf->tempImage == NULL) 
-      {
-         assert(util_format_get_blockwidth(surf->texture->format) == 1);
-         assert(util_format_get_blockheight(surf->texture->format) == 1);
-         alloc_shm_ximage(xm_buf, b, spt->stride[surf->level] /
-                          util_format_get_blocksize(surf->texture->format), surf->height);
-      }
-
-      ximage = xm_buf->tempImage;
-      ximage->data = xm_buf->data;
-
-      /* _debug_printf("XSHM\n"); */
-      XShmPutImage(b->xm_visual->display, b->drawable, b->gc,
-                   ximage, 0, 0, 0, 0, surf->width, surf->height, False);
-   }
-   else
-#endif
-   {
-      /* display image in Window */
-      ximage = b->tempImage;
-      ximage->data = xm_buf->data;
-
-      /* check that the XImage has been previously initialized */
-      assert(ximage->format);
-      assert(ximage->bitmap_unit);
-
-      /* update XImage's fields */
-      ximage->width = surf->width;
-      ximage->height = surf->height;
-      ximage->bytes_per_line = spt->stride[surf->level];
-
-      /* _debug_printf("XPUT\n"); */
-      XPutImage(b->xm_visual->display, b->drawable, b->gc,
-                ximage, 0, 0, 0, 0, surf->width, surf->height);
-   }
-}
-
-
-static void
-xm_flush_frontbuffer(struct pipe_winsys *pws,
-                     struct pipe_surface *surf,
-                     void *context_private)
-{
-   /*
-    * The front color buffer is actually just another XImage buffer.
-    * This function copies that XImage to the actual X Window.
-    */
-   XMesaContext xmctx = (XMesaContext) context_private;
-   xlib_softpipe_display_surface(xmctx->xm_buffer, surf);
-   xmesa_check_and_update_buffer_size(xmctx, xmctx->xm_buffer);
-}
-
-
-
-static const char *
-xm_get_name(struct pipe_winsys *pws)
-{
-   return "Xlib";
-}
-
-
-static struct pipe_buffer *
-xm_buffer_create(struct pipe_winsys *pws, 
-                 unsigned alignment, 
-                 unsigned usage,
-                 unsigned size)
-{
-   struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-
-   pipe_reference_init(&buffer->base.reference, 1);
-   buffer->base.alignment = alignment;
-   buffer->base.usage = usage;
-   buffer->base.size = size;
-
-   /* align to 16-byte multiple for Cell */
-   buffer->data = align_malloc(size, max(alignment, 16));
-
-   return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
-   struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-   pipe_reference_init(&buffer->base.reference, 1);
-   buffer->base.size = bytes;
-   buffer->userBuffer = TRUE;
-   buffer->data = ptr;
-
-   return &buffer->base;
-}
-
-
-static struct pipe_buffer *
-xm_surface_buffer_create(struct pipe_winsys *winsys,
-                         unsigned width, unsigned height,
-                         enum pipe_format format,
-                         unsigned usage,
-                         unsigned tex_usage,
-                         unsigned *stride)
-{
-   const unsigned alignment = 64;
-   unsigned nblocksy, size;
-
-   nblocksy = util_format_get_nblocksy(format, height);
-   *stride = align(util_format_get_stride(format, width), alignment);
-   size = *stride * nblocksy;
-
-#ifdef USE_XSHM
-   if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
-   {
-      struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-
-      pipe_reference_init(&buffer->base.reference, 1);
-      buffer->base.alignment = alignment;
-      buffer->base.usage = usage;
-      buffer->base.size = size;
-      buffer->userBuffer = FALSE;
-      buffer->shminfo.shmid = -1;
-      buffer->shminfo.shmaddr = (char *) -1;
-      buffer->shm = TRUE;
-         
-      buffer->data = alloc_shm(buffer, size);
-      if (!buffer->data)
-         goto out;
-
-      return &buffer->base;
-         
-   out:
-      if (buffer)
-         FREE(buffer);
-   }
-#endif
-   
-
-   return winsys->buffer_create(winsys, alignment,
-                                usage,
-                                size);
-}
-
-
-/*
- * Fence functions - basically nothing to do, as we don't create any actual
- * fence objects.
- */
-
-static void
-xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
-                   struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
-                   unsigned flag)
-{
-   return 0;
-}
-
-
-static int
-xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
-                unsigned flag)
-{
-   return 0;
-}
-
-
-
-static struct pipe_winsys *
-xlib_create_softpipe_winsys( void )
-{
-   static struct xmesa_pipe_winsys *ws = NULL;
-
-   if (!ws) {
-      ws = CALLOC_STRUCT(xmesa_pipe_winsys);
-
-      /* Fill in this struct with callbacks that pipe will need to
-       * communicate with the window system, buffer manager, etc. 
-       */
-      ws->base.buffer_create = xm_buffer_create;
-      ws->base.user_buffer_create = xm_user_buffer_create;
-      ws->base.buffer_map = xm_buffer_map;
-      ws->base.buffer_unmap = xm_buffer_unmap;
-      ws->base.buffer_destroy = xm_buffer_destroy;
-
-      ws->base.surface_buffer_create = xm_surface_buffer_create;
-
-      ws->base.fence_reference = xm_fence_reference;
-      ws->base.fence_signalled = xm_fence_signalled;
-      ws->base.fence_finish = xm_fence_finish;
-
-      ws->base.flush_frontbuffer = xm_flush_frontbuffer;
-      ws->base.get_name = xm_get_name;
-   }
-
-   return &ws->base;
-}
-
+#include "softpipe/sp_texture.h"
+#include "softpipe/sp_screen.h"
+#include "state_tracker/sw_winsys.h"
 
 static struct pipe_screen *
 xlib_create_softpipe_screen( void )
 {
-   struct pipe_winsys *winsys;
+   struct sw_winsys *winsys;
    struct pipe_screen *screen;
 
-   winsys = xlib_create_softpipe_winsys();
+   winsys = xlib_create_sw_winsys();
    if (winsys == NULL)
       return NULL;
 
@@ -498,6 +56,18 @@ fail:
 }
 
 
+static void
+xlib_softpipe_display_surface(struct xmesa_buffer *xm_buffer,
+                              struct pipe_surface *surf)
+{
+   struct softpipe_texture *texture = softpipe_texture(surf->texture);
+
+   assert(texture->dt);
+   if (texture->dt)
+      xlib_sw_display(xm_buffer, texture->dt);
+}
+
+
 struct xm_driver xlib_softpipe_driver = 
 {
    .create_pipe_screen = xlib_create_softpipe_screen,
diff --git a/src/gallium/winsys/xlib/xlib_sw_winsys.c b/src/gallium/winsys/xlib/xlib_sw_winsys.c
new file mode 100644 (file)
index 0000000..e4b02ba
--- /dev/null
@@ -0,0 +1,394 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * 
+ **************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell
+ *   Brian Paul
+ */
+
+
+
+#include "xm_api.h"
+
+#undef ASSERT
+#undef Elements
+
+#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "state_tracker/sw_winsys.h"
+
+#include "xlib.h"
+
+/**
+ * Subclass of pipe_buffer for Xlib winsys.
+ * Low-level OS/window system memory buffer
+ */
+struct xm_displaytarget
+{
+   enum pipe_format format;
+   unsigned width;
+   unsigned height;
+   unsigned stride;
+
+   void *data;
+   void *mapped;
+
+   XImage *tempImage;
+#ifdef USE_XSHM
+   int shm;
+   XShmSegmentInfo shminfo;
+#endif
+};
+
+
+/**
+ * Subclass of sw_winsys for Xlib winsys
+ */
+struct xmesa_sw_winsys
+{
+   struct sw_winsys base;
+/*   struct xmesa_visual *xm_visual; */
+};
+
+
+
+/** Cast wrapper */
+static INLINE struct xm_displaytarget *
+xm_displaytarget( struct sw_displaytarget *dt )
+{
+   return (struct xm_displaytarget *)dt;
+}
+
+
+/**
+ * X Shared Memory Image extension code
+ */
+
+#ifdef USE_XSHM
+
+static volatile int mesaXErrorFlag = 0;
+
+/**
+ * Catches potential Xlib errors.
+ */
+static int
+mesaHandleXError(Display *dpy, XErrorEvent *event)
+{
+   (void) dpy;
+   (void) event;
+   mesaXErrorFlag = 1;
+   return 0;
+}
+
+
+static char *alloc_shm(struct xm_displaytarget *buf, unsigned size)
+{
+   XShmSegmentInfo *const shminfo = & buf->shminfo;
+
+   shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
+   if (shminfo->shmid < 0) {
+      return NULL;
+   }
+
+   shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
+   if (shminfo->shmaddr == (char *) -1) {
+      shmctl(shminfo->shmid, IPC_RMID, 0);
+      return NULL;
+   }
+
+   shminfo->readOnly = False;
+   return shminfo->shmaddr;
+}
+
+
+/**
+ * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
+ */
+static void
+alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
+                 struct xmesa_buffer *xmb,
+                 unsigned width, unsigned height)
+{
+   /*
+    * We have to do a _lot_ of error checking here to be sure we can
+    * really use the XSHM extension.  It seems different servers trigger
+    * errors at different points if the extension won't work.  Therefore
+    * we have to be very careful...
+    */
+   int (*old_handler)(Display *, XErrorEvent *);
+
+   xm_buffer->tempImage = XShmCreateImage(xmb->xm_visual->display,
+                                  xmb->xm_visual->visinfo->visual,
+                                  xmb->xm_visual->visinfo->depth,
+                                  ZPixmap,
+                                  NULL,
+                                  &xm_buffer->shminfo,
+                                  width, height);
+   if (xm_buffer->tempImage == NULL) {
+      xm_buffer->shm = 0;
+      return;
+   }
+
+
+   mesaXErrorFlag = 0;
+   old_handler = XSetErrorHandler(mesaHandleXError);
+   /* This may trigger the X protocol error we're ready to catch: */
+   XShmAttach(xmb->xm_visual->display, &xm_buffer->shminfo);
+   XSync(xmb->xm_visual->display, False);
+
+   if (mesaXErrorFlag) {
+      /* we are on a remote display, this error is normal, don't print it */
+      XFlush(xmb->xm_visual->display);
+      mesaXErrorFlag = 0;
+      XDestroyImage(xm_buffer->tempImage);
+      xm_buffer->tempImage = NULL;
+      xm_buffer->shm = 0;
+      (void) XSetErrorHandler(old_handler);
+      return;
+   }
+
+   xm_buffer->shm = 1;
+}
+
+#endif /* USE_XSHM */
+
+static boolean
+xm_is_displaytarget_format_supported( struct sw_winsys *ws,
+                                      enum pipe_format format )
+{
+   /* TODO: check visuals or other sensible thing here */
+   return TRUE;
+}
+
+
+static void *
+xm_displaytarget_map(struct sw_winsys *ws,
+                     struct sw_displaytarget *dt,
+                     unsigned flags)
+{
+   struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+   xm_dt->mapped = xm_dt->data;
+   return xm_dt->mapped;
+}
+
+static void
+xm_displaytarget_unmap(struct sw_winsys *ws,
+                       struct sw_displaytarget *dt)
+{
+   struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+   xm_dt->mapped = NULL;
+}
+
+static void
+xm_displaytarget_destroy(struct sw_winsys *ws,
+                         struct sw_displaytarget *dt)
+{
+   struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+
+   if (xm_dt->data) {
+#ifdef USE_XSHM
+      if (xm_dt->shminfo.shmid >= 0) {
+         shmdt(xm_dt->shminfo.shmaddr);
+         shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0);
+         
+         xm_dt->shminfo.shmid = -1;
+         xm_dt->shminfo.shmaddr = (char *) -1;
+      }
+      else
+#endif
+         FREE(xm_dt->data);
+   }
+
+   FREE(xm_dt);
+}
+
+
+/**
+ * Display/copy the image in the surface into the X window specified
+ * by the XMesaBuffer.
+ */
+void
+xlib_sw_display(struct xmesa_buffer *xm_buffer,
+                struct sw_displaytarget *dt)
+{
+   XImage *ximage;
+   struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+   static boolean no_swap = 0;
+   static boolean firsttime = 1;
+
+   if (firsttime) {
+      no_swap = getenv("SP_NO_RAST") != NULL;
+      firsttime = 0;
+   }
+
+   if (no_swap)
+      return;
+
+#ifdef USE_XSHM
+   if (xm_dt->shm)
+   {
+      if (xm_dt->tempImage == NULL)
+      {
+         assert(util_format_get_blockwidth(xm_dt->format) == 1);
+         assert(util_format_get_blockheight(xm_dt->format) == 1);
+         alloc_shm_ximage(xm_dt, xm_buffer,
+                          xm_dt->stride / util_format_get_blocksize(xm_dt->format),
+                          xm_dt->height);
+      }
+
+      ximage = xm_dt->tempImage;
+      ximage->data = xm_dt->data;
+
+      /* _debug_printf("XSHM\n"); */
+      XShmPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
+                   ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False);
+   }
+   else
+#endif
+   {
+      /* display image in Window */
+      ximage = xm_dt->tempImage;
+      ximage->data = xm_dt->data;
+
+      /* check that the XImage has been previously initialized */
+      assert(ximage->format);
+      assert(ximage->bitmap_unit);
+
+      /* update XImage's fields */
+      ximage->width = xm_dt->width;
+      ximage->height = xm_dt->height;
+      ximage->bytes_per_line = xm_dt->stride;
+
+      /* _debug_printf("XPUT\n"); */
+      XPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
+                ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height);
+   }
+}
+
+/**
+ * Display/copy the image in the surface into the X window specified
+ * by the XMesaBuffer.
+ */
+static void
+xm_displaytarget_display(struct sw_winsys *ws,
+                         struct sw_displaytarget *dt,
+                         void *context_private)
+{
+   XMesaContext xmctx = (XMesaContext) context_private;
+   struct xmesa_buffer *xm_buffer = xmctx->xm_buffer;
+   xm_sw_display(xm_buffer, dt);
+}
+
+
+static struct sw_displaytarget *
+xm_displaytarget_create(struct sw_winsys *winsys,
+                        enum pipe_format format,
+                        unsigned width, unsigned height,
+                        unsigned alignment,
+                        unsigned *stride)
+{
+   struct xm_displaytarget *xm_dt = CALLOC_STRUCT(xm_displaytarget);
+   unsigned nblocksy, size;
+
+   xm_dt = CALLOC_STRUCT(xm_displaytarget);
+   if(!xm_dt)
+      goto no_xm_dt;
+
+   xm_dt->format = format;
+   xm_dt->width = width;
+   xm_dt->height = height;
+
+   nblocksy = util_format_get_nblocksy(format, height);
+   xm_dt->stride = align(util_format_get_stride(format, width), alignment);
+   size = xm_dt->stride * nblocksy;
+
+#ifdef USE_XSHM
+   if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
+   {
+      xm_dt->shminfo.shmid = -1;
+      xm_dt->shminfo.shmaddr = (char *) -1;
+      xm_dt->shm = TRUE;
+         
+      xm_dt->data = alloc_shm(xm_dt, size);
+      if(!xm_dt->data)
+         goto no_data;
+   }
+#endif
+
+   if(!xm_dt->data) {
+      xm_dt->data = align_malloc(size, alignment);
+      if(!xm_dt->data)
+         goto no_data;
+   }
+
+   *stride = xm_dt->stride;
+   return (struct sw_displaytarget *)xm_dt;
+
+no_data:
+   FREE(xm_dt);
+no_xm_dt:
+   return NULL;
+}
+
+
+static void
+xm_destroy( struct sw_winsys *ws )
+{
+   FREE(ws);
+}
+
+
+struct sw_winsys *
+xlib_create_sw_winsys( void )
+{
+   struct xmesa_sw_winsys *ws;
+
+   ws = CALLOC_STRUCT(xmesa_sw_winsys);
+   if (!ws)
+      return NULL;
+
+   ws->base.destroy = xm_destroy;
+
+   ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
+
+   ws->base.displaytarget_create = xm_displaytarget_create;
+   ws->base.displaytarget_map = xm_displaytarget_map;
+   ws->base.displaytarget_unmap = xm_displaytarget_unmap;
+   ws->base.displaytarget_destroy = xm_displaytarget_destroy;
+
+   ws->base.displaytarget_display = xm_displaytarget_display;
+
+   return &ws->base;
+}
+