Add DRI driver that uses the mesa swrast module.
authorGeorge Sapountzis <gsap7@yahoo.gr>
Sun, 11 May 2008 11:43:40 +0000 (14:43 +0300)
committerKristian Høgsberg <krh@redhat.com>
Tue, 20 May 2008 20:03:44 +0000 (16:03 -0400)
configure.ac
include/GL/internal/dri_interface.h
src/mesa/drivers/dri/swrast/Makefile [new file with mode: 0644]
src/mesa/drivers/dri/swrast/swrast.c [new file with mode: 0644]
src/mesa/drivers/dri/swrast/swrast_priv.h [new file with mode: 0644]
src/mesa/drivers/dri/swrast/swrast_span.c [new file with mode: 0644]
src/mesa/drivers/dri/swrast/swrast_spantemp.h [new file with mode: 0644]

index 6aac482e1a8bd962c8aa66feb57539337448c9dc..6f05108f344b1e5ba719fcf6b88e723bfe8c6c4d 100644 (file)
@@ -537,14 +537,14 @@ if test "$mesa_driver" = dri; then
             # be used.
             if test "x$DRI_DIRS" = x; then
                 DRI_DIRS="i915 i965 mach64 mga r128 r200 r300 radeon \
-                    savage tdfx unichrome"
+                    savage tdfx unichrome swrast"
             fi
             ;;
         powerpc*)
             # Build only the drivers for cards that exist on PowerPC.
             # At some point MGA will be added, but not yet.
             if test "x$DRI_DIRS" = x; then
-                DRI_DIRS="mach64 r128 r200 r300 radeon tdfx"
+                DRI_DIRS="mach64 r128 r200 r300 radeon tdfx swrast"
             fi
             ;;
         esac
@@ -564,7 +564,7 @@ if test "$mesa_driver" = dri; then
         # to use the new interface.
         if test "x$DRI_DIRS" = x; then
             DRI_DIRS="i810 i915 i965 mach64 mga r128 r200 r300 radeon tdfx \
-                unichrome savage sis"
+                unichrome savage sis swrast"
         fi
         ;;
     esac
@@ -572,7 +572,7 @@ if test "$mesa_driver" = dri; then
     # default drivers
     if test "x$DRI_DIRS" = x; then
         DRI_DIRS="i810 i915 i965 mach64 mga r128 r200 r300 radeon s3v \
-            savage sis tdfx trident unichrome ffb"
+            savage sis tdfx trident unichrome ffb swrast"
     fi
 
     DRI_DIRS=`echo "$DRI_DIRS" | $SED 's/  */ /g'`
index 1bfb5efb2c8961d8070cc89af73c75079abc81e2..033d7a4ae448990cbc54dad70013a314d6537402 100644 (file)
@@ -67,6 +67,7 @@ typedef struct __DRImediaStreamCounterExtensionRec    __DRImediaStreamCounterExtens
 typedef struct __DRItexOffsetExtensionRec      __DRItexOffsetExtension;
 typedef struct __DRItexBufferExtensionRec      __DRItexBufferExtension;
 typedef struct __DRIlegacyExtensionRec         __DRIlegacyExtension;
+typedef struct __DRIswrastExtensionRec         __DRIswrastExtension;
 /*@}*/
 
 
@@ -256,6 +257,7 @@ typedef struct __DRIgetDrawableInfoExtensionRec __DRIgetDrawableInfoExtension;
 typedef struct __DRIsystemTimeExtensionRec __DRIsystemTimeExtension;
 typedef struct __DRIdamageExtensionRec __DRIdamageExtension;
 typedef struct __DRIloaderExtensionRec __DRIloaderExtension;
+typedef struct __DRIswrastLoaderExtensionRec __DRIswrastLoaderExtension;
 
 
 /**
@@ -357,6 +359,40 @@ struct __DRIloaderExtensionRec {
                       int num_rects, void *loaderPrivate);
 };
 
+#define __DRI_SWRAST_IMAGE_OP_DRAW     1
+#define __DRI_SWRAST_IMAGE_OP_CLEAR    2
+#define __DRI_SWRAST_IMAGE_OP_SWAP     3
+
+/**
+ * SWRast Loader extension.
+ */
+#define __DRI_SWRAST_LOADER "DRI_SWRastLoader"
+#define __DRI_SWRAST_LOADER_VERSION 1
+struct __DRIswrastLoaderExtensionRec {
+    __DRIextension base;
+
+    /*
+     * Drawable position and size
+     */
+    void (*getDrawableInfo)(__DRIdrawable *drawable,
+                           int *x, int *y, int *width, int *height,
+                           void *loaderPrivate);
+
+    /**
+     * Put image to drawable
+     */
+    void (*putImage)(__DRIdrawable *drawable, int op,
+                    int x, int y, int width, int height, char *data,
+                    void *loaderPrivate);
+
+    /**
+     * Get image from drawable
+     */
+    void (*getImage)(__DRIdrawable *drawable,
+                    int x, int y, int width, int height, char *data,
+                    void *loaderPrivate);
+};
+
 /**
  * The remaining extensions describe driver extensions, immediately
  * available interfaces provided by the driver.  To start using the
@@ -569,4 +605,25 @@ struct __DRIlegacyExtensionRec {
                                      void *loaderPrivate);
 };
 
+/**
+ * This extension provides alternative screen, drawable and context
+ * constructors for swrast DRI functionality.  This is used in
+ * conjunction with the core extension.
+ */
+#define __DRI_SWRAST "DRI_SWRast"
+#define __DRI_SWRAST_VERSION 1
+
+struct __DRIswrastExtensionRec {
+    __DRIextension base;
+
+    __DRIscreen *(*createNewScreen)(int screen,
+                                   const __DRIextension **extensions,
+                                   const __DRIconfig ***driver_configs,
+                                   void *loaderPrivate);
+
+    __DRIdrawable *(*createNewDrawable)(__DRIscreen *screen,
+                                       const __DRIconfig *config,
+                                       void *loaderPrivate);
+};
+
 #endif
diff --git a/src/mesa/drivers/dri/swrast/Makefile b/src/mesa/drivers/dri/swrast/Makefile
new file mode 100644 (file)
index 0000000..eb58f4c
--- /dev/null
@@ -0,0 +1,74 @@
+# src/mesa/drivers/dri/swrast/Makefile
+
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = swrast_dri.so
+
+DRIVER_SOURCES = \
+       swrast.c \
+       swrast_span.c
+
+C_SOURCES = \
+       $(COMMON_SOURCES) \
+       $(DRIVER_SOURCES)
+
+########################################
+
+MESA_MODULES = $(TOP)/src/mesa/libmesa.a
+
+COMMON_SOURCES = \
+       ../../common/driverfuncs.c
+
+ifeq ($(WINDOW_SYSTEM),dri)
+COMMON_SOURCES += \
+       ../common/utils.c
+endif
+
+OBJECTS = $(C_SOURCES:.c=.o)
+
+### Include directories
+INCLUDES = \
+       -I. \
+       -I$(TOP)/include \
+       -I$(TOP)/src/mesa \
+       -I$(TOP)/src/mesa/main \
+       -I$(TOP)/src/mesa/glapi
+
+ifeq ($(WINDOW_SYSTEM),dri)
+INCLUDES += \
+       -I$(TOP)/src/mesa/drivers/dri/common \
+       $(LIBDRM_CFLAGS)
+endif
+
+##### RULES #####
+
+.c.o:
+       $(CC) -c $(INCLUDES) $(CFLAGS) $< -o $@
+
+
+##### TARGETS #####
+
+default: depend $(LIBNAME)
+
+
+$(LIBNAME): $(OBJECTS) $(MESA_MODULES) Makefile
+       $(TOP)/bin/mklib -ldflags '$(LDFLAGS)' -noprefix -o $@ \
+               $(OBJECTS) $(MESA_MODULES) $(GLCORE_LIB_DEPS)
+
+
+depend: $(C_SOURCES)
+       touch depend
+       $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(C_SOURCES) \
+               > /dev/null
+
+
+clean:
+       -rm -f *.o *.so
+       -rm -f depend depend.bak
+
+install: $(LIBNAME)
+       $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
+       $(INSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
+
+include depend
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
new file mode 100644 (file)
index 0000000..5c2b346
--- /dev/null
@@ -0,0 +1,714 @@
+/*
+ * Copyright (C) 2008 George Sapountzis <gsap7@yahoo.gr>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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.
+ */
+
+/* TODO:
+ *   - depth 8 (ci8, r3g3b2 ?)
+ *   - XMesaResizeBuffers() ?
+ *     add it to __DRIcoreExtension or own extension (GL_MESA_resize_buffers) ?
+ *   - GLX_MESA_copy_sub_buffer
+ *   - GLX_EXT_texture_from_pixmap
+ *
+ * BUGS:
+ *   - winpos, glxpixmap: draw half width only with xorg at depth 16,
+ *     they somehow manage to get a wrong drawable with depth 32,
+ *     the "depth 32" visual is the composite overlay visual which is the
+ *     only available single-buffer visual with glx_visuals "min" ...
+ *
+ *   there is clearly something wrong with GLX visual setup, the assumption
+ *   that GLX runs before composite no longer holds ...
+ *
+ *   at depth 16:
+ *   with glx_visuals "min", the composite overlay visual is added
+ *   with glx_visuals "all", segfaults when moving cursor over glx window
+ *
+ *   - texobj: loses textures at depth 32
+ *   - texcyl: crashes mesa with "Linear Filtrered"
+ *
+ * DONE:
+ *   - round image (i.e. backbuffer) pitch to 32 bits
+ *   - depth 16
+ *   - front-buffer rendering - depths, wincopy
+ *   - GLX_SGI_make_current_read (wincopy with front)
+ */
+
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+#include "context.h"
+#include "extensions.h"
+#include "framebuffer.h"
+#include "imports.h"
+#include "renderbuffer.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+#include "vbo/vbo.h"
+#include "drivers/common/driverfuncs.h"
+
+#include "swrast_priv.h"
+
+
+#define need_GL_VERSION_1_3
+#define need_GL_VERSION_1_4
+#define need_GL_VERSION_1_5
+#define need_GL_VERSION_2_0
+
+/* sw extensions for imaging */
+#define need_GL_EXT_blend_color
+#define need_GL_EXT_blend_minmax
+#define need_GL_EXT_convolution
+#define need_GL_EXT_histogram
+#define need_GL_SGI_color_table
+
+/* sw extensions not associated with some GL version */
+#define need_GL_ARB_shader_objects
+#define need_GL_ARB_vertex_program
+#define need_GL_APPLE_vertex_array_object
+#define need_GL_ATI_fragment_shader
+#define need_GL_EXT_depth_bounds_test
+#define need_GL_EXT_framebuffer_object
+#define need_GL_EXT_framebuffer_blit
+#define need_GL_EXT_gpu_program_parameters
+#define need_GL_EXT_paletted_texture
+#define need_GL_IBM_multimode_draw_arrays
+#define need_GL_MESA_resize_buffers
+#define need_GL_NV_vertex_program
+#define need_GL_NV_fragment_program
+
+#include "extension_helper.h"
+#include "utils.h"
+
+const struct dri_extension card_extensions[] =
+{
+    { "GL_VERSION_1_3",                        GL_VERSION_1_3_functions },
+    { "GL_VERSION_1_4",                        GL_VERSION_1_4_functions },
+    { "GL_VERSION_1_5",                        GL_VERSION_1_5_functions },
+    { "GL_VERSION_2_0",                        GL_VERSION_2_0_functions },
+
+    { "GL_EXT_blend_color",            GL_EXT_blend_color_functions },
+    { "GL_EXT_blend_minmax",           GL_EXT_blend_minmax_functions },
+    { "GL_EXT_convolution",            GL_EXT_convolution_functions },
+    { "GL_EXT_histogram",              GL_EXT_histogram_functions },
+    { "GL_SGI_color_table",            GL_SGI_color_table_functions },
+
+    { "GL_ARB_shader_objects",         GL_ARB_shader_objects_functions },
+    { "GL_ARB_vertex_program",         GL_ARB_vertex_program_functions },
+    { "GL_APPLE_vertex_array_object",  GL_APPLE_vertex_array_object_functions },
+    { "GL_ATI_fragment_shader",                GL_ATI_fragment_shader_functions },
+    { "GL_EXT_depth_bounds_test",      GL_EXT_depth_bounds_test_functions },
+    { "GL_EXT_framebuffer_object",     GL_EXT_framebuffer_object_functions },
+    { "GL_EXT_framebuffer_blit",       GL_EXT_framebuffer_blit_functions },
+    { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions },
+    { "GL_EXT_paletted_texture",       GL_EXT_paletted_texture_functions },
+    { "GL_IBM_multimode_draw_arrays",  GL_IBM_multimode_draw_arrays_functions },
+    { "GL_MESA_resize_buffers",                GL_MESA_resize_buffers_functions },
+    { "GL_NV_vertex_program",          GL_NV_vertex_program_functions },
+    { "GL_NV_fragment_program",                GL_NV_fragment_program_functions },
+    { NULL,                            NULL }
+};
+
+static void
+setupLoaderExtensions(__DRIscreen *psp,
+                     const __DRIextension **extensions)
+{
+    int i;
+
+    for (i = 0; extensions[i]; i++) {
+       if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0)
+           psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
+    }
+}
+
+static __DRIconfig **
+swrastFillInModes(__DRIscreen *psp,
+                 unsigned pixel_bits, unsigned depth_bits,
+                 unsigned stencil_bits, GLboolean have_back_buffer)
+{
+   __DRIconfig **configs;
+   unsigned depth_buffer_factor;
+   unsigned back_buffer_factor;
+   GLenum fb_format;
+   GLenum fb_type;
+
+   /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
+    * support pageflipping at all.
+    */
+   static const GLenum back_buffer_modes[] = {
+      GLX_NONE, GLX_SWAP_UNDEFINED_OML
+   };
+
+   u_int8_t depth_bits_array[3];
+   u_int8_t stencil_bits_array[3];
+
+   depth_bits_array[0] = 0;
+   depth_bits_array[1] = depth_bits;
+   depth_bits_array[2] = depth_bits;
+
+   stencil_bits_array[0] = 0;
+   stencil_bits_array[1] = 0;
+   stencil_bits_array[2] = stencil_bits;
+
+   depth_buffer_factor = 3;
+   back_buffer_factor = 2;
+
+   if (pixel_bits == 16) {
+      fb_format = GL_RGB;
+      fb_type = GL_UNSIGNED_SHORT_5_6_5;
+   }
+   else {
+      fb_format = GL_BGRA;
+      fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+   }
+
+   configs = driCreateConfigs(fb_format, fb_type,
+                             depth_bits_array, stencil_bits_array,
+                             depth_buffer_factor, back_buffer_modes,
+                             back_buffer_factor);
+   if (configs == NULL) {
+      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
+              __LINE__);
+      return NULL;
+   }
+
+   return configs;
+}
+
+static __DRIscreen *
+driCreateNewScreen(int scrn, const __DRIextension **extensions,
+                  const __DRIconfig ***driver_configs, void *data)
+{
+    static const __DRIextension *emptyExtensionList[] = { NULL };
+    __DRIscreen *psp;
+
+    (void) data;
+
+    TRACE;
+
+    psp = _mesa_calloc(sizeof(*psp));
+    if (!psp)
+       return NULL;
+
+    setupLoaderExtensions(psp, extensions);
+
+    psp->num = scrn;
+    psp->extensions = emptyExtensionList;
+
+    *driver_configs = driConcatConfigs(swrastFillInModes(psp, 16, 16, 0, 1),
+                                      swrastFillInModes(psp, 32, 24, 8, 1));
+
+    driInitExtensions( NULL, card_extensions, GL_FALSE );
+
+    return psp;
+}
+
+static void driDestroyScreen(__DRIscreen *psp)
+{
+    TRACE;
+
+    if (psp) {
+       _mesa_free(psp);
+    }
+}
+
+static const __DRIextension **driGetExtensions(__DRIscreen *psp)
+{
+    TRACE;
+
+    return psp->extensions;
+}
+
+
+/**
+ * swrast_buffer.c
+ */
+
+static GLuint
+choose_pixel_format(const GLvisual *v)
+{
+    if (v->rgbMode) {
+       /* XXX 24bpp packed, 8bpp, xmesa gets bitsPerPixel from xserver */
+       int bpp = v->rgbBits;
+       if (bpp == 24)
+           bpp = 32;
+
+       if (bpp == 32
+           && v->redMask   == 0xff0000
+           && v->greenMask == 0x00ff00
+           && v->blueMask  == 0x0000ff)
+           return PF_A8R8G8B8;
+       else if (bpp == 16
+           && v->redMask   == 0xf800
+           && v->greenMask == 0x07e0
+           && v->blueMask  == 0x001f)
+           return PF_R5G6B5;
+    }
+    else {
+       if (v->indexBits == 8)
+           return PF_CI8;
+    }
+
+    _mesa_problem( NULL, "unexpected format in %s", __FUNCTION__ );
+    return 0;
+}
+
+static void
+swrast_delete_renderbuffer(struct gl_renderbuffer *rb)
+{
+    TRACE;
+
+    _mesa_free(rb->Data);
+    _mesa_free(rb);
+}
+
+static GLboolean
+swrast_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+                          GLenum internalFormat, GLuint width, GLuint height)
+{
+    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+    int bpp;
+
+    TRACE;
+
+    rb->Data = NULL;
+    rb->Width = width;
+    rb->Height = height;
+
+    switch (internalFormat) {
+    case GL_RGB:
+       bpp = rb->RedBits + rb->GreenBits + rb->BlueBits;
+       break;
+    case GL_RGBA:
+       bpp = rb->RedBits + rb->GreenBits + rb->BlueBits + rb->AlphaBits;
+       break;
+    case GL_COLOR_INDEX8_EXT:
+       bpp = rb->IndexBits;
+       break;
+    default:
+       _mesa_problem( NULL, "unexpected format in %s", __FUNCTION__ );
+       return GL_FALSE;
+    }
+
+    /* always pad to 32 bits */
+    xrb->pitch = ((width * bpp + 0x1f) & ~0x1f) / 8;
+
+    return GL_TRUE;
+}
+
+static GLboolean
+swrast_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+                       GLenum internalFormat, GLuint width, GLuint height)
+{
+    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+
+    TRACE;
+
+    _mesa_free(rb->Data);
+
+    (void) swrast_alloc_front_storage(ctx, rb, internalFormat, width, height);
+
+    rb->Data = _mesa_malloc(height * xrb->pitch);
+
+    return GL_TRUE;
+}
+
+static struct swrast_renderbuffer *
+swrast_new_renderbuffer(const GLvisual *visual, GLboolean front)
+{
+    struct swrast_renderbuffer *xrb = _mesa_calloc(sizeof *xrb);
+    GLuint pixel_format;
+
+    TRACE;
+
+    if (xrb) {
+       _mesa_init_renderbuffer(&xrb->Base, 0);
+
+       pixel_format = choose_pixel_format(visual);
+
+       xrb->Base.Delete = swrast_delete_renderbuffer;
+       if (front) {
+           xrb->Base.AllocStorage = swrast_alloc_front_storage;
+           swrast_set_span_funcs_pixmap(xrb, pixel_format);
+       }
+       else {
+           xrb->Base.AllocStorage = swrast_alloc_back_storage;
+           swrast_set_span_funcs_ximage(xrb, pixel_format);
+       }
+
+       switch (pixel_format) {
+       case PF_A8R8G8B8:
+           xrb->Base.InternalFormat = GL_RGBA;
+           xrb->Base._BaseFormat = GL_RGBA;
+           xrb->Base.DataType = GL_UNSIGNED_BYTE;
+           xrb->Base.RedBits   = 8 * sizeof(GLubyte);
+           xrb->Base.GreenBits = 8 * sizeof(GLubyte);
+           xrb->Base.BlueBits  = 8 * sizeof(GLubyte);
+           xrb->Base.AlphaBits = 8 * sizeof(GLubyte);
+           break;
+       case PF_R5G6B5:
+           xrb->Base.InternalFormat = GL_RGB;
+           xrb->Base._BaseFormat = GL_RGB;
+           xrb->Base.DataType = GL_UNSIGNED_BYTE;
+           xrb->Base.RedBits   = 5 * sizeof(GLubyte);
+           xrb->Base.GreenBits = 6 * sizeof(GLubyte);
+           xrb->Base.BlueBits  = 5 * sizeof(GLubyte);
+           xrb->Base.AlphaBits = 0;
+           break;
+       case PF_CI8:
+           xrb->Base.InternalFormat = GL_COLOR_INDEX8_EXT;
+           xrb->Base._BaseFormat = GL_COLOR_INDEX;
+           xrb->Base.DataType = GL_UNSIGNED_BYTE;
+           xrb->Base.IndexBits = 8 * sizeof(GLubyte);
+           break;
+       default:
+           return NULL;
+       }
+    }
+    return xrb;
+}
+
+static __DRIdrawable *
+driCreateNewDrawable(__DRIscreen *screen,
+                    const __DRIconfig *config, void *data)
+{
+    __DRIdrawable *buf;
+    struct swrast_renderbuffer *frontrb, *backrb;
+
+    TRACE;
+
+    buf = _mesa_calloc(sizeof *buf);
+    if (!buf)
+       return NULL;
+
+    buf->loaderPrivate = data;
+
+    buf->driScreenPriv = screen;
+
+    buf->row = _mesa_malloc(MAX_WIDTH * 4);
+
+    /* basic framebuffer setup */
+    _mesa_initialize_framebuffer(&buf->Base, &config->modes);
+
+    /* add front renderbuffer */
+    frontrb = swrast_new_renderbuffer(&config->modes, GL_TRUE);
+    _mesa_add_renderbuffer(&buf->Base, BUFFER_FRONT_LEFT, &frontrb->Base);
+
+    /* add back renderbuffer */
+    if (config->modes.doubleBufferMode) {
+       backrb = swrast_new_renderbuffer(&config->modes, GL_FALSE);
+       _mesa_add_renderbuffer(&buf->Base, BUFFER_BACK_LEFT, &backrb->Base);
+    }
+
+    /* add software renderbuffers */
+    _mesa_add_soft_renderbuffers(&buf->Base,
+                                GL_FALSE, /* color */
+                                config->modes.haveDepthBuffer,
+                                config->modes.haveStencilBuffer,
+                                config->modes.haveAccumBuffer,
+                                GL_FALSE, /* alpha */
+                                GL_FALSE /* aux bufs */);
+
+    return buf;
+}
+
+static void
+driDestroyDrawable(__DRIdrawable *buf)
+{
+    TRACE;
+
+    if (buf) {
+       struct gl_framebuffer *fb = &buf->Base;
+
+       _mesa_free(buf->row);
+
+       fb->DeletePending = GL_TRUE;
+       _mesa_unreference_framebuffer(&fb);
+    }
+}
+
+static void driSwapBuffers(__DRIdrawable *buf)
+{
+    GET_CURRENT_CONTEXT(ctx);
+
+    struct swrast_renderbuffer *frontrb =
+       swrast_renderbuffer(buf->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+    struct swrast_renderbuffer *backrb =
+       swrast_renderbuffer(buf->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+
+    __DRIscreen *screen = buf->driScreenPriv;
+
+    TRACE;
+
+    /* check for signle-buffered */
+    if (backrb == NULL)
+       return;
+
+    /* check if swapping currently bound buffer */
+    if (ctx && ctx->DrawBuffer == &(buf->Base)) {
+       /* flush pending rendering */
+       _mesa_notifySwapBuffers(ctx);
+    }
+
+    screen->swrast_loader->putImage(buf, __DRI_SWRAST_IMAGE_OP_SWAP,
+                                   0, 0,
+                                   frontrb->Base.Width,
+                                   frontrb->Base.Height,
+                                   backrb->Base.Data,
+                                   buf->loaderPrivate);
+}
+
+
+/**
+ * swrast_dd.c
+ */
+
+static void
+get_window_size( GLframebuffer *fb, GLsizei *w, GLsizei *h )
+{
+    __DRIdrawable *buf = swrast_drawable(fb);
+    __DRIscreen *screen = buf->driScreenPriv;
+    int x, y;
+
+    screen->swrast_loader->getDrawableInfo(buf,
+                                          &x, &y, w, h,
+                                          buf->loaderPrivate);
+}
+
+static void
+swrast_check_and_update_window_size( GLcontext *ctx, GLframebuffer *fb )
+{
+    GLsizei width, height;
+
+    get_window_size(fb, &width, &height);
+    if (fb->Width != width || fb->Height != height) {
+       _mesa_resize_framebuffer(ctx, fb, width, height);
+    }
+}
+
+static const GLubyte *
+get_string(GLcontext *ctx, GLenum pname)
+{
+    (void) ctx;
+    switch (pname) {
+       case GL_VENDOR:
+           return (const GLubyte *) "Mesa Project";
+       case GL_RENDERER:
+           return (const GLubyte *) "X.Org";
+       default:
+           return NULL;
+    }
+}
+
+static void
+update_state( GLcontext *ctx, GLuint new_state )
+{
+    /* not much to do here - pass it on */
+    _swrast_InvalidateState( ctx, new_state );
+    _swsetup_InvalidateState( ctx, new_state );
+    _vbo_InvalidateState( ctx, new_state );
+    _tnl_InvalidateState( ctx, new_state );
+}
+
+static void
+viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+    GLframebuffer *draw = ctx->WinSysDrawBuffer;
+    GLframebuffer *read = ctx->WinSysReadBuffer;
+
+    swrast_check_and_update_window_size(ctx, draw);
+    swrast_check_and_update_window_size(ctx, read);
+}
+
+static void
+swrast_init_driver_functions(struct dd_function_table *driver)
+{
+    driver->GetString = get_string;
+    driver->UpdateState = update_state;
+    driver->GetBufferSize = NULL;
+    driver->Viewport = viewport;
+}
+
+
+/**
+ * swrast_context.c
+ */
+
+static __DRIcontext *
+driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
+                   __DRIcontext *shared, void *data)
+{
+    __DRIcontext *ctx;
+    GLcontext *mesaCtx;
+    struct dd_function_table functions;
+
+    TRACE;
+
+    ctx = _mesa_calloc(sizeof *ctx);
+    if (!ctx)
+       return NULL;
+
+    ctx->loaderPrivate = data;
+
+    ctx->driScreenPriv = screen;
+
+    /* build table of device driver functions */
+    _mesa_init_driver_functions(&functions);
+    swrast_init_driver_functions(&functions);
+
+    if (!_mesa_initialize_context(&ctx->Base, &config->modes,
+                                 shared ? &shared->Base : NULL,
+                                 &functions, (void *) ctx)) {
+      _mesa_free(ctx);
+      return NULL;
+    }
+
+    mesaCtx = &ctx->Base;
+
+    /* do bounds checking to prevent segfaults and server crashes! */
+    mesaCtx->Const.CheckArrayBounds = GL_TRUE;
+
+    /* create module contexts */
+    _swrast_CreateContext( mesaCtx );
+    _vbo_CreateContext( mesaCtx );
+    _tnl_CreateContext( mesaCtx );
+    _swsetup_CreateContext( mesaCtx );
+    _swsetup_Wakeup( mesaCtx );
+
+    /* use default TCL pipeline */
+    {
+       TNLcontext *tnl = TNL_CONTEXT(mesaCtx);
+       tnl->Driver.RunPipeline = _tnl_run_pipeline;
+    }
+
+    _mesa_enable_sw_extensions(mesaCtx);
+    _mesa_enable_1_3_extensions(mesaCtx);
+    _mesa_enable_1_4_extensions(mesaCtx);
+    _mesa_enable_1_5_extensions(mesaCtx);
+    _mesa_enable_2_0_extensions(mesaCtx);
+    _mesa_enable_2_1_extensions(mesaCtx);
+
+    return ctx;
+}
+
+static void
+driDestroyContext(__DRIcontext *ctx)
+{
+    GLcontext *mesaCtx;
+    TRACE;
+
+    if (ctx) {
+       mesaCtx = &ctx->Base;
+       _swsetup_DestroyContext( mesaCtx );
+       _swrast_DestroyContext( mesaCtx );
+       _tnl_DestroyContext( mesaCtx );
+       _vbo_DestroyContext( mesaCtx );
+       _mesa_destroy_context( mesaCtx );
+    }
+}
+
+static int
+driCopyContext(__DRIcontext *dst, __DRIcontext *src, unsigned long mask)
+{
+    TRACE;
+
+    _mesa_copy_context(&src->Base, &dst->Base, mask);
+    return GL_TRUE;
+}
+
+static int driBindContext(__DRIcontext *ctx,
+                         __DRIdrawable *draw,
+                         __DRIdrawable *read)
+{
+    GLcontext *mesaCtx;
+    GLframebuffer *mesaDraw;
+    GLframebuffer *mesaRead;
+    TRACE;
+
+    if (ctx) {
+       if (!draw || !read)
+           return GL_FALSE;
+
+       /* check for same context and buffer */
+       mesaCtx = &ctx->Base;
+       mesaDraw = &draw->Base;
+       mesaRead = &read->Base;
+       if (mesaCtx == _mesa_get_current_context()
+           && mesaCtx->DrawBuffer == mesaDraw
+           && mesaCtx->ReadBuffer == mesaRead) {
+           return GL_TRUE;
+       }
+
+       _glapi_check_multithread();
+
+       swrast_check_and_update_window_size(mesaCtx, mesaDraw);
+       if (read != draw)
+           swrast_check_and_update_window_size(mesaCtx, mesaRead);
+
+       _mesa_make_current( mesaCtx,
+                           mesaDraw,
+                           mesaRead );
+    }
+    else {
+       /* unbind */
+       _mesa_make_current( NULL, NULL, NULL );
+    }
+
+    return GL_TRUE;
+}
+
+static int driUnbindContext(__DRIcontext *ctx)
+{
+    TRACE;
+    (void) ctx;
+    _mesa_make_current(NULL, NULL, NULL);
+    return GL_TRUE;
+}
+
+
+static const __DRIcoreExtension driCoreExtension = {
+    { __DRI_CORE, __DRI_CORE_VERSION },
+    NULL,
+    driDestroyScreen,
+    driGetExtensions,
+    driGetConfigAttrib,
+    driIndexConfigAttrib,
+    NULL,
+    driDestroyDrawable,
+    driSwapBuffers,
+    driCreateNewContext,
+    driCopyContext,
+    driDestroyContext,
+    driBindContext,
+    driUnbindContext
+};
+
+static const __DRIswrastExtension driSWRastExtension = {
+    { __DRI_SWRAST, __DRI_SWRAST_VERSION },
+    driCreateNewScreen,
+    driCreateNewDrawable,
+};
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driSWRastExtension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/swrast/swrast_priv.h b/src/mesa/drivers/dri/swrast/swrast_priv.h
new file mode 100644 (file)
index 0000000..d801f88
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Authors:
+ *    George Sapountzis <gsap7@yahoo.gr>
+ */
+
+
+#ifndef _SWRAST_PRIV_H
+#define _SWRAST_PRIV_H
+
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+#include "mtypes.h"
+
+#define DEBUG_CORE     0
+#define DEBUG_SPAN     1
+
+#if DEBUG_CORE
+#define TRACE _mesa_printf("--> %s\n", __FUNCTION__)
+#else
+#define TRACE
+#endif
+
+#if DEBUG_SPAN
+#define TRACE_SPAN _mesa_printf("--> %s\n", __FUNCTION__)
+#else
+#define TRACE_SPAN
+#endif
+
+
+/**
+ * Data types
+ */
+struct __DRIscreenRec {
+    int num;
+
+    const __DRIextension **extensions;
+
+    const __DRIswrastLoaderExtension *swrast_loader;
+};
+
+struct __DRIcontextRec {
+    GLcontext Base;
+
+    void *loaderPrivate;
+
+    __DRIscreen *driScreenPriv;
+};
+
+struct __DRIdrawableRec {
+    GLframebuffer Base;
+
+    void *loaderPrivate;
+
+    __DRIscreen *driScreenPriv;
+
+    char *row;
+};
+
+struct swrast_renderbuffer {
+    struct gl_renderbuffer Base;
+
+    GLuint pitch;
+};
+
+static inline __DRIcontext *
+swrast_context(GLcontext *ctx)
+{
+    return (__DRIcontext *) ctx;
+}
+
+static inline __DRIdrawable *
+swrast_drawable(GLframebuffer *fb)
+{
+    return (__DRIdrawable *) fb;
+}
+
+static inline struct swrast_renderbuffer *
+swrast_renderbuffer(struct gl_renderbuffer *rb)
+{
+    return (struct swrast_renderbuffer *) rb;
+}
+
+
+/**
+ * Pixel formats we support
+ */
+#define PF_CI8        1                /**< Color Index mode */
+#define PF_A8R8G8B8   2                /**< 32-bit TrueColor:  8-A, 8-R, 8-G, 8-B bits */
+#define PF_R5G6B5     3                /**< 16-bit TrueColor:  5-R, 6-G, 5-B bits */
+
+
+/* swrast_span.c */
+
+extern void
+swrast_set_span_funcs_ximage(struct swrast_renderbuffer *xrb,
+                            GLuint pixel_format);
+
+extern void
+swrast_set_span_funcs_pixmap(struct swrast_renderbuffer *xrb,
+                            GLuint pixel_format);
+
+#endif /* _SWRAST_PRIV_H_ */
diff --git a/src/mesa/drivers/dri/swrast/swrast_span.c b/src/mesa/drivers/dri/swrast/swrast_span.c
new file mode 100644 (file)
index 0000000..fd11f28
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Authors:
+ *    George Sapountzis <gsap7@yahoo.gr>
+ */
+
+#include "swrast_priv.h"
+
+#define YFLIP(_xrb, Y) ((_xrb)->Base.Height - (Y) - 1)
+
+/*
+ * Generate code for image span functions.
+ */
+
+/* 32-bit BGRA */
+#define NAME(FUNC) FUNC##_A8R8G8B8
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+   struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+   GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4;
+#define INC_PIXEL_PTR(P) P += 4
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+   DST[3] = VALUE[ACOMP]; \
+   DST[2] = VALUE[RCOMP]; \
+   DST[1] = VALUE[GCOMP]; \
+   DST[0] = VALUE[BCOMP]
+#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
+   DST[3] = 0xff; \
+   DST[2] = VALUE[RCOMP]; \
+   DST[1] = VALUE[GCOMP]; \
+   DST[0] = VALUE[BCOMP]
+#define FETCH_PIXEL(DST, SRC) \
+   DST[ACOMP] = SRC[3]; \
+   DST[RCOMP] = SRC[2]; \
+   DST[GCOMP] = SRC[1]; \
+   DST[BCOMP] = SRC[0]
+
+#include "swrast/s_spantemp.h"
+
+
+/* 16-bit BGR */
+#define NAME(FUNC) FUNC##_R5G6B5
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+   struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+   GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 2;
+#define INC_PIXEL_PTR(P) P += 2
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+   do { \
+   GLushort *p = (GLushort *)DST; \
+   *p = ( (((VALUE[RCOMP]) & 0xf8) << 8) | \
+         (((VALUE[GCOMP]) & 0xfc) << 3) | \
+         (((VALUE[BCOMP]) & 0xf8) >> 3) ); \
+   } while(0)
+#define FETCH_PIXEL(DST, SRC) \
+   do { \
+   GLushort p = *(GLushort *)SRC; \
+   DST[ACOMP] = 0xff; \
+   DST[RCOMP] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
+   DST[GCOMP] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
+   DST[BCOMP] = ((p << 3) & 0xf8) * 255 / 0xf8; \
+   } while(0)
+
+#include "swrast/s_spantemp.h"
+
+
+/* 8-bit color index */
+#define NAME(FUNC) FUNC##_CI8
+#define CI_MODE
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+   struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+   GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X);
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+   *DST = VALUE[0]
+#define FETCH_PIXEL(DST, SRC) \
+   DST = SRC[0]
+
+#include "swrast/s_spantemp.h"
+
+
+/*
+ * Generate code for pixmap span functions.
+ */
+
+/* 32-bit BGRA */
+#define NAME(FUNC) FUNC##_A8R8G8B8_pixmap
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+   struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+   GLubyte *P = (GLubyte *)row;
+#define INC_PIXEL_PTR(P) P += 4
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+   DST[3] = VALUE[ACOMP]; \
+   DST[2] = VALUE[RCOMP]; \
+   DST[1] = VALUE[GCOMP]; \
+   DST[0] = VALUE[BCOMP]
+#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
+   DST[3] = 0xff; \
+   DST[2] = VALUE[RCOMP]; \
+   DST[1] = VALUE[GCOMP]; \
+   DST[0] = VALUE[BCOMP]
+#define FETCH_PIXEL(DST, SRC) \
+   DST[ACOMP] = SRC[3]; \
+   DST[RCOMP] = SRC[2]; \
+   DST[GCOMP] = SRC[1]; \
+   DST[BCOMP] = SRC[0]
+
+#include "swrast_spantemp.h"
+
+
+/* 16-bit BGR */
+#define NAME(FUNC) FUNC##_R5G6B5_pixmap
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+   struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+   GLubyte *P = (GLubyte *)row;
+#define INC_PIXEL_PTR(P) P += 2
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+   do { \
+   GLushort *p = (GLushort *)DST; \
+   *p = ( (((VALUE[RCOMP]) & 0xf8) << 8) | \
+         (((VALUE[GCOMP]) & 0xfc) << 3) | \
+         (((VALUE[BCOMP]) & 0xf8) >> 3) ); \
+   } while(0)
+#define FETCH_PIXEL(DST, SRC) \
+   do { \
+   GLushort p = *(GLushort *)SRC; \
+   DST[ACOMP] = 0xff; \
+   DST[RCOMP] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
+   DST[GCOMP] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
+   DST[BCOMP] = ((p << 3) & 0xf8) * 255 / 0xf8; \
+   } while(0)
+
+#include "swrast_spantemp.h"
+
+
+/* 8-bit color index */
+#define NAME(FUNC) FUNC##_CI8_pixmap
+#define CI_MODE
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+   struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+   GLubyte *P = (GLubyte *)row;
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+   *DST = VALUE[0]
+#define FETCH_PIXEL(DST, SRC) \
+   DST = SRC[0]
+
+#include "swrast_spantemp.h"
+
+
+/*
+ * Images are malloced memory used for private back-buffers.
+ *
+ * BACK_PIXMAP (not supported)
+ * BACK_XIMAGE
+ */
+void
+swrast_set_span_funcs_ximage(struct swrast_renderbuffer *xrb,
+                            GLuint pixel_format)
+{
+    switch (pixel_format) {
+    case PF_A8R8G8B8:
+       xrb->Base.GetRow = get_row_A8R8G8B8;
+       xrb->Base.GetValues = get_values_A8R8G8B8;
+       xrb->Base.PutRow = put_row_A8R8G8B8;
+       xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8;
+       xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8;
+       xrb->Base.PutValues = put_values_A8R8G8B8;
+       xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8;
+       break;
+    case PF_R5G6B5:
+       xrb->Base.GetRow = get_row_R5G6B5;
+       xrb->Base.GetValues = get_values_R5G6B5;
+       xrb->Base.PutRow = put_row_R5G6B5;
+       xrb->Base.PutRowRGB = put_row_rgb_R5G6B5;
+       xrb->Base.PutMonoRow = put_mono_row_R5G6B5;
+       xrb->Base.PutValues = put_values_R5G6B5;
+       xrb->Base.PutMonoValues = put_mono_values_R5G6B5;
+       break;
+    case PF_CI8:
+       xrb->Base.GetRow = get_row_CI8;
+       xrb->Base.GetValues = get_values_CI8;
+       xrb->Base.PutRow = put_row_CI8;
+       xrb->Base.PutMonoRow = put_mono_row_CI8;
+       xrb->Base.PutValues = put_values_CI8;
+       xrb->Base.PutMonoValues = put_mono_values_CI8;
+       break;
+    default:
+       assert(0);
+       return;
+    }
+}
+
+
+/*
+ * Pixmaps are used for front-buffers.
+ *
+ * WINDOW,          An X window
+ * GLXWINDOW,       GLX window
+ * PIXMAP,          GLX pixmap
+ * PBUFFER          GLX Pbuffer
+ */
+void
+swrast_set_span_funcs_pixmap(struct swrast_renderbuffer *xrb,
+                            GLuint pixel_format)
+{
+    switch (pixel_format) {
+    case PF_A8R8G8B8:
+       xrb->Base.GetRow = get_row_A8R8G8B8_pixmap;
+       xrb->Base.GetValues = get_values_A8R8G8B8_pixmap;
+       xrb->Base.PutRow = put_row_A8R8G8B8_pixmap;
+       xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8_pixmap;
+       xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8_pixmap;
+       xrb->Base.PutValues = put_values_A8R8G8B8_pixmap;
+       xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8_pixmap;
+       break;
+    case PF_R5G6B5:
+       xrb->Base.GetRow = get_row_R5G6B5_pixmap;
+       xrb->Base.GetValues = get_values_R5G6B5_pixmap;
+       xrb->Base.PutRow = put_row_R5G6B5_pixmap;
+       xrb->Base.PutRowRGB = put_row_rgb_R5G6B5_pixmap;
+       xrb->Base.PutMonoRow = put_mono_row_R5G6B5_pixmap;
+       xrb->Base.PutValues = put_values_R5G6B5_pixmap;
+       xrb->Base.PutMonoValues = put_mono_values_R5G6B5_pixmap;
+       break;
+    case PF_CI8:
+       xrb->Base.GetRow = get_row_CI8_pixmap;
+       xrb->Base.GetValues = get_values_CI8_pixmap;
+       xrb->Base.PutRow = put_row_CI8_pixmap;
+       xrb->Base.PutMonoRow = put_mono_row_CI8_pixmap;
+       xrb->Base.PutValues = put_values_CI8_pixmap;
+       xrb->Base.PutMonoValues = put_mono_values_CI8_pixmap;
+       break;
+    default:
+       assert(0);
+       return;
+    }
+}
diff --git a/src/mesa/drivers/dri/swrast/swrast_spantemp.h b/src/mesa/drivers/dri/swrast/swrast_spantemp.h
new file mode 100644 (file)
index 0000000..7c60c15
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.1
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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 a modified version of swrast/s_spantemp.h for rendering to X11
+ * drawables. The no-mask paths use a scratch row to avoid repeated calls
+ * to xserver.
+ *
+ * For the mask paths we always use an array of 4 elements of RB_TYPE because
+ * we should pad "image" pitch to 32 bits. 
+ */
+
+
+#ifndef _SWRAST_SPANTEMP_ONCE
+#define _SWRAST_SPANTEMP_ONCE
+
+static inline void
+PUT_PIXEL( GLcontext *glCtx, GLint x, GLint y, GLubyte *p )
+{
+    __DRIcontext *ctx = swrast_context(glCtx);
+    __DRIdrawable *draw = swrast_drawable(glCtx->DrawBuffer);
+
+    __DRIscreen *screen = ctx->driScreenPriv;
+
+    screen->swrast_loader->putImage(draw, __DRI_SWRAST_IMAGE_OP_DRAW,
+                                   x, y, 1, 1, (char *)p,
+                                   draw->loaderPrivate);
+}
+
+
+static inline void
+GET_PIXEL( GLcontext *glCtx, GLint x, GLint y, GLubyte *p )
+{
+    __DRIcontext *ctx = swrast_context(glCtx);
+    __DRIdrawable *draw = swrast_drawable(glCtx->ReadBuffer);
+
+    __DRIscreen *screen = ctx->driScreenPriv;
+
+    screen->swrast_loader->getImage(draw, x, y, 1, 1, (char *)p,
+                                   draw->loaderPrivate);
+}
+
+static inline void
+PUT_ROW( GLcontext *glCtx, GLint x, GLint y, GLuint n, char *row )
+{
+    __DRIcontext *ctx = swrast_context(glCtx);
+    __DRIdrawable *draw = swrast_drawable(glCtx->DrawBuffer);
+
+    __DRIscreen *screen = ctx->driScreenPriv;
+
+    screen->swrast_loader->putImage(draw, __DRI_SWRAST_IMAGE_OP_DRAW,
+                                   x, y, n, 1, row,
+                                   draw->loaderPrivate);
+}
+
+static inline void
+GET_ROW( GLcontext *glCtx, GLint x, GLint y, GLuint n, char *row )
+{
+    __DRIcontext *ctx = swrast_context(glCtx);
+    __DRIdrawable *draw = swrast_drawable(glCtx->ReadBuffer);
+
+    __DRIscreen *screen = ctx->driScreenPriv;
+
+    screen->swrast_loader->getImage(draw, x, y, n, 1, row,
+                                   draw->loaderPrivate);
+}
+
+#endif /* _SWRAST_SPANTEMP_ONCE */
+
+
+/*
+ * Templates for the span/pixel-array write/read functions called via
+ * the gl_renderbuffer's GetRow, GetValues, PutRow, PutMonoRow, PutValues
+ * and PutMonoValues functions.
+ *
+ * Define the following macros before including this file:
+ *   NAME(BASE)  to generate the function name (i.e. add prefix or suffix)
+ *   RB_TYPE  the renderbuffer DataType
+ *   CI_MODE  if set, color index mode, else RGBA
+ *   SPAN_VARS  to declare any local variables
+ *   INIT_PIXEL_PTR(P, X, Y)  to initialize a pointer to a pixel
+ *   INC_PIXEL_PTR(P)  to increment a pixel pointer by one pixel
+ *   STORE_PIXEL(DST, X, Y, VALUE)  to store pixel values in buffer
+ *   FETCH_PIXEL(DST, SRC)  to fetch pixel values from buffer
+ *
+ * Note that in the STORE_PIXEL macros, we also pass in the (X,Y) coordinates
+ * for the pixels to be stored.  This is useful when dithering and probably
+ * ignored otherwise.
+ */
+
+#include "macros.h"
+
+
+#ifdef CI_MODE
+#define RB_COMPONENTS 1
+#elif !defined(RB_COMPONENTS)
+#define RB_COMPONENTS 4
+#endif
+
+
+static void
+NAME(get_row)( GLcontext *ctx, struct gl_renderbuffer *rb,
+               GLuint count, GLint x, GLint y, void *values )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+#ifdef CI_MODE
+   RB_TYPE *dest = (RB_TYPE *) values;
+#else
+   RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
+#endif
+   GLuint i;
+   char *row = swrast_drawable(ctx->DrawBuffer)->row;
+   INIT_PIXEL_PTR(pixel, x, y);
+   GET_ROW( ctx, x, YFLIP(xrb, y), count, row );
+   for (i = 0; i < count; i++) {
+      FETCH_PIXEL(dest[i], pixel);
+      INC_PIXEL_PTR(pixel);
+   }
+   (void) rb;
+}
+
+
+static void
+NAME(get_values)( GLcontext *ctx, struct gl_renderbuffer *rb,
+                  GLuint count, const GLint x[], const GLint y[], void *values )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+#ifdef CI_MODE
+   RB_TYPE *dest = (RB_TYPE *) values;
+#else
+   RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
+#endif
+   GLuint i;
+   for (i = 0; i < count; i++) {
+      RB_TYPE pixel[4];
+      GET_PIXEL(ctx, x[i], YFLIP(xrb, y[i]), pixel);
+      FETCH_PIXEL(dest[i], pixel);
+   }
+   (void) rb;
+}
+
+
+static void
+NAME(put_row)( GLcontext *ctx, struct gl_renderbuffer *rb,
+               GLuint count, GLint x, GLint y,
+               const void *values, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+   const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
+   GLuint i;
+   if (mask) {
+      for (i = 0; i < count; i++) {
+         if (mask[i]) {
+            RB_TYPE pixel[4];
+            STORE_PIXEL(pixel, x + i, y, src[i]);
+            PUT_PIXEL(ctx, x + i, YFLIP(xrb, y), pixel);
+         }
+      }
+   }
+   else {
+      char *row = swrast_drawable(ctx->DrawBuffer)->row;
+      INIT_PIXEL_PTR(pixel, x, y);
+      for (i = 0; i < count; i++) {
+         STORE_PIXEL(pixel, x + i, y, src[i]);
+         INC_PIXEL_PTR(pixel);
+      }
+      PUT_ROW( ctx, x, YFLIP(xrb, y), count, row );
+   }
+   (void) rb;
+}
+
+
+#if !defined(CI_MODE)
+static void
+NAME(put_row_rgb)( GLcontext *ctx, struct gl_renderbuffer *rb,
+                   GLuint count, GLint x, GLint y,
+                   const void *values, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+   const RB_TYPE (*src)[3] = (const RB_TYPE (*)[3]) values;
+   GLuint i;
+   if (mask) {
+      for (i = 0; i < count; i++) {
+         if (mask[i]) {
+            RB_TYPE pixel[4];
+#ifdef STORE_PIXEL_RGB
+            STORE_PIXEL_RGB(pixel, x + i, y, src[i]);
+#else
+            STORE_PIXEL(pixel, x + i, y, src[i]);
+#endif
+            PUT_PIXEL(ctx, x + i, YFLIP(xrb, y), pixel);
+         }
+      }
+   }
+   else {
+      char *row = swrast_drawable(ctx->DrawBuffer)->row;
+      INIT_PIXEL_PTR(pixel, x, y);
+      for (i = 0; i < count; i++) {
+#ifdef STORE_PIXEL_RGB
+         STORE_PIXEL_RGB(pixel, x + i, y, src[i]);
+#else
+         STORE_PIXEL(pixel, x + i, y, src[i]);
+#endif
+         INC_PIXEL_PTR(pixel);
+      }
+      PUT_ROW( ctx, x, YFLIP(xrb, y), count, row );
+   }
+   (void) rb;
+}
+#endif
+
+
+static void
+NAME(put_mono_row)( GLcontext *ctx, struct gl_renderbuffer *rb,
+                    GLuint count, GLint x, GLint y,
+                    const void *value, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+   const RB_TYPE *src = (const RB_TYPE *) value;
+   GLuint i;
+   if (mask) {
+      for (i = 0; i < count; i++) {
+         if (mask[i]) {
+            RB_TYPE pixel[4];
+            STORE_PIXEL(pixel, x + i, y, src);
+            PUT_PIXEL(ctx, x + i, YFLIP(xrb, y), pixel);
+         }
+      }
+   }
+   else {
+      char *row = swrast_drawable(ctx->DrawBuffer)->row;
+      INIT_PIXEL_PTR(pixel, x, y);
+      for (i = 0; i < count; i++) {
+         STORE_PIXEL(pixel, x + i, y, src);
+         INC_PIXEL_PTR(pixel);
+      }
+      PUT_ROW( ctx, x, YFLIP(xrb, y), count, row );
+   }
+   (void) rb;
+}
+
+
+static void
+NAME(put_values)( GLcontext *ctx, struct gl_renderbuffer *rb,
+                  GLuint count, const GLint x[], const GLint y[],
+                  const void *values, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+   const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
+   GLuint i;
+   ASSERT(mask);
+   for (i = 0; i < count; i++) {
+      if (mask[i]) {
+         RB_TYPE pixel[4];
+         STORE_PIXEL(pixel, x[i], y[i], src[i]);
+         PUT_PIXEL(ctx, x[i], YFLIP(xrb, y[i]), pixel);
+      }
+   }
+   (void) rb;
+}
+
+
+static void
+NAME(put_mono_values)( GLcontext *ctx, struct gl_renderbuffer *rb,
+                       GLuint count, const GLint x[], const GLint y[],
+                       const void *value, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+   const RB_TYPE *src = (const RB_TYPE *) value;
+   GLuint i;
+   ASSERT(mask);
+   for (i = 0; i < count; i++) {
+      if (mask[i]) {
+         RB_TYPE pixel[4];
+         STORE_PIXEL(pixel, x[i], y[i], src);
+         PUT_PIXEL(ctx, x[i], YFLIP(xrb, y[i]), pixel);
+      }
+   }
+   (void) rb;
+}
+
+
+#undef NAME
+#undef RB_TYPE
+#undef RB_COMPONENTS
+#undef CI_MODE
+#undef SPAN_VARS
+#undef INIT_PIXEL_PTR
+#undef INC_PIXEL_PTR
+#undef STORE_PIXEL
+#undef STORE_PIXEL_RGB
+#undef FETCH_PIXEL