diff options
Diffstat (limited to 'src/mesa')
| -rw-r--r-- | src/mesa/drivers/dri/swrast/Makefile | 74 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/swrast/swrast.c | 714 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/swrast/swrast_priv.h | 126 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/swrast/swrast_span.c | 271 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/swrast/swrast_spantemp.h | 328 | 
5 files changed, 1513 insertions, 0 deletions
| diff --git a/src/mesa/drivers/dri/swrast/Makefile b/src/mesa/drivers/dri/swrast/Makefile new file mode 100644 index 0000000000..eb58f4c733 --- /dev/null +++ b/src/mesa/drivers/dri/swrast/Makefile @@ -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 index 0000000000..5c2b346e3e --- /dev/null +++ b/src/mesa/drivers/dri/swrast/swrast.c @@ -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 index 0000000000..d801f88f07 --- /dev/null +++ b/src/mesa/drivers/dri/swrast/swrast_priv.h @@ -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 index 0000000000..fd11f2866e --- /dev/null +++ b/src/mesa/drivers/dri/swrast/swrast_span.c @@ -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 index 0000000000..7c60c15974 --- /dev/null +++ b/src/mesa/drivers/dri/swrast/swrast_spantemp.h @@ -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 | 
