Home | History | Annotate | Download | only in x11
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 
     26 /*
     27  * This file contains "accelerated" point, line, and triangle functions.
     28  * It should be fairly easy to write new special-purpose point, line or
     29  * triangle functions and hook them into this module.
     30  */
     31 
     32 
     33 #include "glxheader.h"
     34 #include "main/macros.h"
     35 #include "main/mtypes.h"
     36 #include "xmesaP.h"
     37 
     38 /* Internal swrast includes:
     39  */
     40 #include "swrast/s_depth.h"
     41 #include "swrast/s_points.h"
     42 #include "swrast/s_lines.h"
     43 #include "swrast/s_context.h"
     44 
     45 
     46 /**********************************************************************/
     47 /***                    Point rendering                             ***/
     48 /**********************************************************************/
     49 
     50 
     51 /*
     52  * Render an array of points into a pixmap, any pixel format.
     53  */
     54 #if 000
     55 /* XXX don't use this, it doesn't dither correctly */
     56 static void draw_points_ANY_pixmap( struct gl_context *ctx, const SWvertex *vert )
     57 {
     58    XMesaContext xmesa = XMESA_CONTEXT(ctx);
     59    XMesaDisplay *dpy = xmesa->xm_visual->display;
     60    XMesaDrawable buffer = xmesa->xm_buffer->buffer;
     61    XMesaGC gc = xmesa->xm_buffer->gc;
     62 
     63    if (xmesa->xm_visual->mesa_visual.RGBAflag) {
     64       register int x, y;
     65       const GLubyte *color = vert->color;
     66       unsigned long pixel = xmesa_color_to_pixel( xmesa,
     67 						  color[0], color[1],
     68 						  color[2], color[3],
     69 						  xmesa->pixelformat);
     70       XMesaSetForeground( dpy, gc, pixel );
     71       x = (GLint) vert->win[0];
     72       y = YFLIP( xrb, (GLint) vert->win[1] );
     73       XMesaDrawPoint( dpy, buffer, gc, x, y);
     74    }
     75    else {
     76       /* Color index mode */
     77       register int x, y;
     78       XMesaSetForeground( dpy, gc, vert->index );
     79       x =                         (GLint) vert->win[0];
     80       y = YFLIP( xrb, (GLint) vert->win[1] );
     81       XMesaDrawPoint( dpy, buffer, gc, x, y);
     82    }
     83 }
     84 #endif
     85 
     86 
     87 /* Override the swrast point-selection function.  Try to use one of
     88  * our internal point functions, otherwise fall back to the standard
     89  * swrast functions.
     90  */
     91 void xmesa_choose_point( struct gl_context *ctx )
     92 {
     93 #if 0
     94    XMesaContext xmesa = XMESA_CONTEXT(ctx);
     95    SWcontext *swrast = SWRAST_CONTEXT(ctx);
     96 
     97    if (ctx->RenderMode == GL_RENDER
     98        && ctx->Point.Size == 1.0F && !ctx->Point.SmoothFlag
     99        && swrast->_RasterMask == 0
    100        && ctx->Texture._MaxEnabledTexImageUnit == -1
    101        && xmesa->xm_buffer->buffer != XIMAGE) {
    102       swrast->Point = draw_points_ANY_pixmap;
    103    }
    104    else {
    105       _swrast_choose_point( ctx );
    106    }
    107 #else
    108    _swrast_choose_point( ctx );
    109 #endif
    110 }
    111 
    112 
    113 
    114 /**********************************************************************/
    115 /***                      Line rendering                            ***/
    116 /**********************************************************************/
    117 
    118 
    119 #if CHAN_BITS == 8
    120 
    121 
    122 #define GET_XRB(XRB)  struct xmesa_renderbuffer *XRB = \
    123    xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0])
    124 
    125 
    126 /*
    127  * Draw a flat-shaded, PF_TRUECOLOR line into an XImage.
    128  */
    129 #define NAME flat_TRUECOLOR_line
    130 #define SETUP_CODE					\
    131    XMesaContext xmesa = XMESA_CONTEXT(ctx);		\
    132    GET_XRB(xrb);					\
    133    const GLubyte *color = vert1->color;			\
    134    unsigned long pixel;					\
    135    PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
    136 #define CLIP_HACK 1
    137 #define PLOT(X,Y) XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel );
    138 #include "swrast/s_linetemp.h"
    139 
    140 
    141 
    142 /*
    143  * Draw a flat-shaded, PF_8A8B8G8R line into an XImage.
    144  */
    145 #define NAME flat_8A8B8G8R_line
    146 #define SETUP_CODE						\
    147    GET_XRB(xrb);						\
    148    const GLubyte *color = vert1->color;				\
    149    GLuint pixel = PACK_8A8B8G8R(color[0], color[1], color[2], color[3]);
    150 #define PIXEL_TYPE GLuint
    151 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
    152 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
    153 #define CLIP_HACK 1
    154 #define PLOT(X,Y) *pixelPtr = pixel;
    155 #include "swrast/s_linetemp.h"
    156 
    157 
    158 
    159 /*
    160  * Draw a flat-shaded, PF_8A8R8G8B line into an XImage.
    161  */
    162 #define NAME flat_8A8R8G8B_line
    163 #define SETUP_CODE						\
    164    GET_XRB(xrb);						\
    165    const GLubyte *color = vert1->color;				\
    166    GLuint pixel = PACK_8A8R8G8B(color[0], color[1], color[2], color[3]);
    167 #define PIXEL_TYPE GLuint
    168 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
    169 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
    170 #define CLIP_HACK 1
    171 #define PLOT(X,Y) *pixelPtr = pixel;
    172 #include "swrast/s_linetemp.h"
    173 
    174 
    175 
    176 /*
    177  * Draw a flat-shaded, PF_8R8G8B line into an XImage.
    178  */
    179 #define NAME flat_8R8G8B_line
    180 #define SETUP_CODE						\
    181    GET_XRB(xrb);						\
    182    const GLubyte *color = vert1->color;				\
    183    GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
    184 #define PIXEL_TYPE GLuint
    185 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
    186 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
    187 #define CLIP_HACK 1
    188 #define PLOT(X,Y) *pixelPtr = pixel;
    189 #include "swrast/s_linetemp.h"
    190 
    191 
    192 
    193 /*
    194  * Draw a flat-shaded, PF_8R8G8B24 line into an XImage.
    195  */
    196 #define NAME flat_8R8G8B24_line
    197 #define SETUP_CODE						\
    198    GET_XRB(xrb);						\
    199    const GLubyte *color = vert1->color;
    200 #define PIXEL_TYPE bgr_t
    201 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
    202 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y)
    203 #define CLIP_HACK 1
    204 #define PLOT(X,Y) {			\
    205       pixelPtr->r = color[RCOMP];	\
    206       pixelPtr->g = color[GCOMP];	\
    207       pixelPtr->b = color[BCOMP];	\
    208 }
    209 #include "swrast/s_linetemp.h"
    210 
    211 
    212 
    213 /*
    214  * Draw a flat-shaded, PF_5R6G5B line into an XImage.
    215  */
    216 #define NAME flat_5R6G5B_line
    217 #define SETUP_CODE						\
    218    GET_XRB(xrb);						\
    219    const GLubyte *color = vert1->color;				\
    220    GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
    221 #define PIXEL_TYPE GLushort
    222 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
    223 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
    224 #define CLIP_HACK 1
    225 #define PLOT(X,Y) *pixelPtr = pixel;
    226 #include "swrast/s_linetemp.h"
    227 
    228 
    229 
    230 /*
    231  * Draw a flat-shaded, PF_DITHER_5R6G5B line into an XImage.
    232  */
    233 #define NAME flat_DITHER_5R6G5B_line
    234 #define SETUP_CODE						\
    235    GET_XRB(xrb);						\
    236    XMesaContext xmesa = XMESA_CONTEXT(ctx);			\
    237    const GLubyte *color = vert1->color;
    238 #define PIXEL_TYPE GLushort
    239 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
    240 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
    241 #define CLIP_HACK 1
    242 #define PLOT(X,Y) PACK_TRUEDITHER( *pixelPtr, X, Y, color[0], color[1], color[2] );
    243 #include "swrast/s_linetemp.h"
    244 
    245 
    246 
    247 /*
    248  * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage.
    249  */
    250 #define NAME flat_TRUECOLOR_z_line
    251 #define SETUP_CODE						\
    252    GET_XRB(xrb);						\
    253    XMesaContext xmesa = XMESA_CONTEXT(ctx);			\
    254    const GLubyte *color = vert1->color;				\
    255    unsigned long pixel;						\
    256    PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
    257 #define INTERP_Z 1
    258 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
    259 #define CLIP_HACK 1
    260 #define PLOT(X,Y)							\
    261 	if (Z < *zPtr) {						\
    262 	   *zPtr = Z;							\
    263            XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel);		\
    264 	}
    265 #include "swrast/s_linetemp.h"
    266 
    267 
    268 
    269 /*
    270  * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage.
    271  */
    272 #define NAME flat_8A8B8G8R_z_line
    273 #define SETUP_CODE						\
    274    GET_XRB(xrb);						\
    275    const GLubyte *color = vert1->color;				\
    276    GLuint pixel = PACK_8A8B8G8R(color[0], color[1], color[2], color[3]);
    277 #define INTERP_Z 1
    278 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
    279 #define PIXEL_TYPE GLuint
    280 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
    281 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y)
    282 #define CLIP_HACK 1
    283 #define PLOT(X,Y)		\
    284 	if (Z < *zPtr) {	\
    285 	   *zPtr = Z;		\
    286 	   *pixelPtr = pixel;	\
    287 	}
    288 #include "swrast/s_linetemp.h"
    289 
    290 
    291 
    292 /*
    293  * Draw a flat-shaded, Z-less, PF_8A8R8G8B line into an XImage.
    294  */
    295 #define NAME flat_8A8R8G8B_z_line
    296 #define SETUP_CODE						\
    297    GET_XRB(xrb);						\
    298    const GLubyte *color = vert1->color;				\
    299    GLuint pixel = PACK_8A8R8G8B(color[0], color[1], color[2], color[3]);
    300 #define INTERP_Z 1
    301 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
    302 #define PIXEL_TYPE GLuint
    303 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
    304 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y)
    305 #define CLIP_HACK 1
    306 #define PLOT(X,Y)		\
    307 	if (Z < *zPtr) {	\
    308 	   *zPtr = Z;		\
    309 	   *pixelPtr = pixel;	\
    310 	}
    311 #include "swrast/s_linetemp.h"
    312 
    313 
    314 
    315 /*
    316  * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage.
    317  */
    318 #define NAME flat_8R8G8B_z_line
    319 #define SETUP_CODE						\
    320    GET_XRB(xrb);						\
    321    const GLubyte *color = vert1->color;				\
    322    GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
    323 #define INTERP_Z 1
    324 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
    325 #define PIXEL_TYPE GLuint
    326 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
    327 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y)
    328 #define CLIP_HACK 1
    329 #define PLOT(X,Y)		\
    330 	if (Z < *zPtr) {	\
    331 	   *zPtr = Z;		\
    332 	   *pixelPtr = pixel;	\
    333 	}
    334 #include "swrast/s_linetemp.h"
    335 
    336 
    337 
    338 /*
    339  * Draw a flat-shaded, Z-less, PF_8R8G8B24 line into an XImage.
    340  */
    341 #define NAME flat_8R8G8B24_z_line
    342 #define SETUP_CODE						\
    343    GET_XRB(xrb);						\
    344    const GLubyte *color = vert1->color;
    345 #define INTERP_Z 1
    346 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
    347 #define PIXEL_TYPE bgr_t
    348 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
    349 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X,Y)
    350 #define CLIP_HACK 1
    351 #define PLOT(X,Y)			\
    352 	if (Z < *zPtr) {		\
    353 	   *zPtr = Z;			\
    354            pixelPtr->r = color[RCOMP];	\
    355            pixelPtr->g = color[GCOMP];	\
    356            pixelPtr->b = color[BCOMP];	\
    357 	}
    358 #include "swrast/s_linetemp.h"
    359 
    360 
    361 
    362 /*
    363  * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage.
    364  */
    365 #define NAME flat_5R6G5B_z_line
    366 #define SETUP_CODE						\
    367    GET_XRB(xrb);						\
    368    const GLubyte *color = vert1->color;				\
    369    GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
    370 #define INTERP_Z 1
    371 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
    372 #define PIXEL_TYPE GLushort
    373 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
    374 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X,Y)
    375 #define CLIP_HACK 1
    376 #define PLOT(X,Y)		\
    377 	if (Z < *zPtr) {	\
    378 	   *zPtr = Z;		\
    379 	   *pixelPtr = pixel;	\
    380 	}
    381 #include "swrast/s_linetemp.h"
    382 
    383 
    384 
    385 /*
    386  * Draw a flat-shaded, Z-less, PF_DITHER_5R6G5B line into an XImage.
    387  */
    388 #define NAME flat_DITHER_5R6G5B_z_line
    389 #define SETUP_CODE					\
    390    GET_XRB(xrb);						\
    391    XMesaContext xmesa = XMESA_CONTEXT(ctx);		\
    392    const GLubyte *color = vert1->color;
    393 #define INTERP_Z 1
    394 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
    395 #define PIXEL_TYPE GLushort
    396 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
    397 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X,Y)
    398 #define CLIP_HACK 1
    399 #define PLOT(X,Y)		\
    400 	if (Z < *zPtr) {	\
    401 	   *zPtr = Z;		\
    402 	   PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \
    403 	}
    404 #include "swrast/s_linetemp.h"
    405 
    406 
    407 
    408 /**
    409  * Draw fast, XOR line with XDrawLine in front color buffer.
    410  * WARNING: this isn't fully OpenGL conformant because different pixels
    411  * will be hit versus using the other line functions.
    412  * Don't use the code in X server GLcore module since we need a wrapper
    413  * for the XSetLineAttributes() function call.
    414  */
    415 static void
    416 xor_line(struct gl_context *ctx, const SWvertex *vert0, const SWvertex *vert1)
    417 {
    418    XMesaContext xmesa = XMESA_CONTEXT(ctx);
    419    XMesaDisplay *dpy = xmesa->xm_visual->display;
    420    XMesaGC gc = xmesa->xm_buffer->gc;
    421    GET_XRB(xrb);
    422    unsigned long pixel = xmesa_color_to_pixel(ctx,
    423                                               vert1->color[0], vert1->color[1],
    424                                               vert1->color[2], vert1->color[3],
    425                                               xmesa->pixelformat);
    426    int x0 =            (GLint) vert0->attrib[VARYING_SLOT_POS][0];
    427    int y0 = YFLIP(xrb, (GLint) vert0->attrib[VARYING_SLOT_POS][1]);
    428    int x1 =            (GLint) vert1->attrib[VARYING_SLOT_POS][0];
    429    int y1 = YFLIP(xrb, (GLint) vert1->attrib[VARYING_SLOT_POS][1]);
    430    XMesaSetForeground(dpy, gc, pixel);
    431    XMesaSetFunction(dpy, gc, GXxor);
    432    XSetLineAttributes(dpy, gc, (int) ctx->Line.Width,
    433                       LineSolid, CapButt, JoinMiter);
    434    XDrawLine(dpy, xrb->pixmap, gc, x0, y0, x1, y1);
    435    XMesaSetFunction(dpy, gc, GXcopy);  /* this gc is used elsewhere */
    436 }
    437 
    438 
    439 #endif /* CHAN_BITS == 8 */
    440 
    441 
    442 /**
    443  * Return pointer to line drawing function, or NULL if we should use a
    444  * swrast fallback.
    445  */
    446 static swrast_line_func
    447 get_line_func(struct gl_context *ctx)
    448 {
    449 #if CHAN_BITS == 8
    450    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    451    XMesaContext xmesa = XMESA_CONTEXT(ctx);
    452    const struct xmesa_renderbuffer *xrb;
    453 
    454    if ((ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_FRONT_LEFT) &&
    455        (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_BACK_LEFT))
    456       return (swrast_line_func) NULL;
    457    if (ctx->RenderMode != GL_RENDER)      return (swrast_line_func) NULL;
    458    if (ctx->Line.SmoothFlag)              return (swrast_line_func) NULL;
    459    if (ctx->Texture._MaxEnabledTexImageUnit != -1)        return (swrast_line_func) NULL;
    460    if (ctx->Light.ShadeModel != GL_FLAT)  return (swrast_line_func) NULL;
    461    if (ctx->Line.StippleFlag)             return (swrast_line_func) NULL;
    462    if (swrast->_RasterMask & MULTI_DRAW_BIT) return (swrast_line_func) NULL;
    463 
    464    xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
    465 
    466    if (xrb->ximage
    467        && swrast->_RasterMask==DEPTH_BIT
    468        && ctx->Depth.Func==GL_LESS
    469        && ctx->Depth.Mask==GL_TRUE
    470        && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
    471        && ctx->Line.Width==1.0F) {
    472       switch (xmesa->pixelformat) {
    473          case PF_Truecolor:
    474             return flat_TRUECOLOR_z_line;
    475          case PF_8A8B8G8R:
    476             return flat_8A8B8G8R_z_line;
    477          case PF_8A8R8G8B:
    478             return flat_8A8R8G8B_z_line;
    479          case PF_8R8G8B:
    480             return flat_8R8G8B_z_line;
    481          case PF_8R8G8B24:
    482             return flat_8R8G8B24_z_line;
    483          case PF_5R6G5B:
    484             return flat_5R6G5B_z_line;
    485          case PF_Dither_5R6G5B:
    486             return flat_DITHER_5R6G5B_z_line;
    487          default:
    488             return (swrast_line_func)NULL;
    489       }
    490    }
    491    if (xrb->ximage
    492        && swrast->_RasterMask==0
    493        && ctx->Line.Width==1.0F) {
    494       switch (xmesa->pixelformat) {
    495          case PF_Truecolor:
    496             return flat_TRUECOLOR_line;
    497          case PF_8A8B8G8R:
    498             return flat_8A8B8G8R_line;
    499          case PF_8A8R8G8B:
    500             return flat_8A8R8G8B_line;
    501          case PF_8R8G8B:
    502             return flat_8R8G8B_line;
    503          case PF_8R8G8B24:
    504             return flat_8R8G8B24_line;
    505          case PF_5R6G5B:
    506             return flat_5R6G5B_line;
    507          case PF_Dither_5R6G5B:
    508             return flat_DITHER_5R6G5B_line;
    509 	 default:
    510 	    return (swrast_line_func)NULL;
    511       }
    512    }
    513 
    514    if (ctx->DrawBuffer->_NumColorDrawBuffers == 1
    515        && ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT
    516        && swrast->_RasterMask == LOGIC_OP_BIT
    517        && ctx->Color.LogicOp == GL_XOR
    518        && !ctx->Line.StippleFlag
    519        && !ctx->Line.SmoothFlag) {
    520       return xor_line;
    521    }
    522 
    523 #endif /* CHAN_BITS == 8 */
    524    return (swrast_line_func) NULL;
    525 }
    526 
    527 
    528 /**
    529  * Override for the swrast line-selection function.  Try to use one
    530  * of our internal line functions, otherwise fall back to the
    531  * standard swrast functions.
    532  */
    533 void
    534 xmesa_choose_line(struct gl_context *ctx)
    535 {
    536    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    537 
    538    if (!(swrast->Line = get_line_func( ctx )))
    539       _swrast_choose_line( ctx );
    540 }
    541