xm_line.c revision 7117f1b4
1/*
2 * Mesa 3-D graphics library
3 * Version:  6.5
4 *
5 * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR 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 "depth.h"
35#include "macros.h"
36#include "mtypes.h"
37#include "xmesaP.h"
38
39/* Internal swrast includes:
40 */
41#include "swrast/s_depth.h"
42#include "swrast/s_points.h"
43#include "swrast/s_lines.h"
44#include "swrast/s_context.h"
45
46
47/**********************************************************************/
48/***                    Point rendering                             ***/
49/**********************************************************************/
50
51
52/*
53 * Render an array of points into a pixmap, any pixel format.
54 */
55#if 000
56/* XXX don't use this, it doesn't dither correctly */
57static void draw_points_ANY_pixmap( GLcontext *ctx, const SWvertex *vert )
58{
59   XMesaContext xmesa = XMESA_CONTEXT(ctx);
60   XMesaDisplay *dpy = xmesa->xm_visual->display;
61   XMesaDrawable buffer = xmesa->xm_buffer->buffer;
62   XMesaGC gc = xmesa->xm_buffer->gc;
63
64   if (xmesa->xm_visual->mesa_visual.RGBAflag) {
65      register int x, y;
66      const GLubyte *color = vert->color;
67      unsigned long pixel = xmesa_color_to_pixel( xmesa,
68						  color[0], color[1],
69						  color[2], color[3],
70						  xmesa->pixelformat);
71      XMesaSetForeground( dpy, gc, pixel );
72      x = (GLint) vert->win[0];
73      y = YFLIP( xrb, (GLint) vert->win[1] );
74      XMesaDrawPoint( dpy, buffer, gc, x, y);
75   }
76   else {
77      /* Color index mode */
78      register int x, y;
79      XMesaSetForeground( dpy, gc, vert->index );
80      x =                         (GLint) vert->win[0];
81      y = YFLIP( xrb, (GLint) vert->win[1] );
82      XMesaDrawPoint( dpy, buffer, gc, x, y);
83   }
84}
85#endif
86
87
88/* Override the swrast point-selection function.  Try to use one of
89 * our internal point functions, otherwise fall back to the standard
90 * swrast functions.
91 */
92void xmesa_choose_point( GLcontext *ctx )
93{
94#if 0
95   XMesaContext xmesa = XMESA_CONTEXT(ctx);
96   SWcontext *swrast = SWRAST_CONTEXT(ctx);
97
98   if (ctx->RenderMode == GL_RENDER
99       && ctx->Point.Size == 1.0F && !ctx->Point.SmoothFlag
100       && swrast->_RasterMask == 0
101       && !ctx->Texture._EnabledUnits
102       && xmesa->xm_buffer->buffer != XIMAGE) {
103      swrast->Point = draw_points_ANY_pixmap;
104   }
105   else {
106      _swrast_choose_point( ctx );
107   }
108#else
109   _swrast_choose_point( ctx );
110#endif
111}
112
113
114
115/**********************************************************************/
116/***                      Line rendering                            ***/
117/**********************************************************************/
118
119
120#if CHAN_BITS == 8
121
122
123#define GET_XRB(XRB)  struct xmesa_renderbuffer *XRB = \
124   xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped)
125
126
127/*
128 * Draw a flat-shaded, PF_TRUECOLOR line into an XImage.
129 */
130#define NAME flat_TRUECOLOR_line
131#define SETUP_CODE					\
132   XMesaContext xmesa = XMESA_CONTEXT(ctx);		\
133   GET_XRB(xrb);					\
134   const GLubyte *color = vert1->color;			\
135   unsigned long pixel;					\
136   PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
137#define CLIP_HACK 1
138#define PLOT(X,Y) XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel );
139#include "swrast/s_linetemp.h"
140
141
142
143/*
144 * Draw a flat-shaded, PF_8A8B8G8R line into an XImage.
145 */
146#define NAME flat_8A8B8G8R_line
147#define SETUP_CODE						\
148   GET_XRB(xrb);						\
149   const GLubyte *color = vert1->color;				\
150   GLuint pixel = PACK_8A8B8G8R(color[0], color[1], color[2], color[3]);
151#define PIXEL_TYPE GLuint
152#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
153#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
154#define CLIP_HACK 1
155#define PLOT(X,Y) *pixelPtr = pixel;
156#include "swrast/s_linetemp.h"
157
158
159
160/*
161 * Draw a flat-shaded, PF_8A8R8G8B line into an XImage.
162 */
163#define NAME flat_8A8R8G8B_line
164#define SETUP_CODE						\
165   GET_XRB(xrb);						\
166   const GLubyte *color = vert1->color;				\
167   GLuint pixel = PACK_8A8R8G8B(color[0], color[1], color[2], color[3]);
168#define PIXEL_TYPE GLuint
169#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
170#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
171#define CLIP_HACK 1
172#define PLOT(X,Y) *pixelPtr = pixel;
173#include "swrast/s_linetemp.h"
174
175
176
177/*
178 * Draw a flat-shaded, PF_8R8G8B line into an XImage.
179 */
180#define NAME flat_8R8G8B_line
181#define SETUP_CODE						\
182   GET_XRB(xrb);						\
183   const GLubyte *color = vert1->color;				\
184   GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
185#define PIXEL_TYPE GLuint
186#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
187#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
188#define CLIP_HACK 1
189#define PLOT(X,Y) *pixelPtr = pixel;
190#include "swrast/s_linetemp.h"
191
192
193
194/*
195 * Draw a flat-shaded, PF_8R8G8B24 line into an XImage.
196 */
197#define NAME flat_8R8G8B24_line
198#define SETUP_CODE						\
199   GET_XRB(xrb);						\
200   const GLubyte *color = vert1->color;
201#define PIXEL_TYPE bgr_t
202#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
203#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y)
204#define CLIP_HACK 1
205#define PLOT(X,Y) {			\
206      pixelPtr->r = color[RCOMP];	\
207      pixelPtr->g = color[GCOMP];	\
208      pixelPtr->b = color[BCOMP];	\
209}
210#include "swrast/s_linetemp.h"
211
212
213
214/*
215 * Draw a flat-shaded, PF_5R6G5B line into an XImage.
216 */
217#define NAME flat_5R6G5B_line
218#define SETUP_CODE						\
219   GET_XRB(xrb);						\
220   const GLubyte *color = vert1->color;				\
221   GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
222#define PIXEL_TYPE GLushort
223#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
224#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
225#define CLIP_HACK 1
226#define PLOT(X,Y) *pixelPtr = pixel;
227#include "swrast/s_linetemp.h"
228
229
230
231/*
232 * Draw a flat-shaded, PF_DITHER_5R6G5B line into an XImage.
233 */
234#define NAME flat_DITHER_5R6G5B_line
235#define SETUP_CODE						\
236   GET_XRB(xrb);						\
237   XMesaContext xmesa = XMESA_CONTEXT(ctx);			\
238   const GLubyte *color = vert1->color;
239#define PIXEL_TYPE GLushort
240#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
241#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
242#define CLIP_HACK 1
243#define PLOT(X,Y) PACK_TRUEDITHER( *pixelPtr, X, Y, color[0], color[1], color[2] );
244#include "swrast/s_linetemp.h"
245
246
247
248
249/*
250 * Draw a flat-shaded, PF_DITHER 8-bit line into an XImage.
251 */
252#define NAME flat_DITHER8_line
253#define SETUP_CODE						\
254   GET_XRB(xrb);						\
255   const GLubyte *color = vert1->color;				\
256   GLint r = color[0], g = color[1], b = color[2];		\
257   DITHER_SETUP;
258#define PIXEL_TYPE GLubyte
259#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
260#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y)
261#define CLIP_HACK 1
262#define PLOT(X,Y) *pixelPtr = DITHER(X,Y,r,g,b);
263#include "swrast/s_linetemp.h"
264
265
266
267/*
268 * Draw a flat-shaded, PF_LOOKUP 8-bit line into an XImage.
269 */
270#define NAME flat_LOOKUP8_line
271#define SETUP_CODE						\
272   GET_XRB(xrb);						\
273   const GLubyte *color = vert1->color;				\
274   GLubyte pixel;						\
275   LOOKUP_SETUP;						\
276   pixel = (GLubyte) LOOKUP( color[0], color[1], color[2] );
277#define PIXEL_TYPE GLubyte
278#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
279#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y)
280#define CLIP_HACK 1
281#define PLOT(X,Y) *pixelPtr = pixel;
282#include "swrast/s_linetemp.h"
283
284
285
286/*
287 * Draw a flat-shaded, PF_HPCR line into an XImage.
288 */
289#define NAME flat_HPCR_line
290#define SETUP_CODE						\
291   GET_XRB(xrb);						\
292   XMesaContext xmesa = XMESA_CONTEXT(ctx);			\
293   const GLubyte *color = vert1->color;				\
294   GLint r = color[0], g = color[1], b = color[2];
295#define PIXEL_TYPE GLubyte
296#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
297#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y)
298#define CLIP_HACK 1
299#define PLOT(X,Y) *pixelPtr = (GLubyte) DITHER_HPCR(X,Y,r,g,b);
300#include "swrast/s_linetemp.h"
301
302
303
304
305/*
306 * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage.
307 */
308#define NAME flat_TRUECOLOR_z_line
309#define SETUP_CODE						\
310   GET_XRB(xrb);						\
311   XMesaContext xmesa = XMESA_CONTEXT(ctx);			\
312   const GLubyte *color = vert1->color;				\
313   unsigned long pixel;						\
314   PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
315#define INTERP_Z 1
316#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
317#define CLIP_HACK 1
318#define PLOT(X,Y)							\
319	if (Z < *zPtr) {						\
320	   *zPtr = Z;							\
321           XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel);		\
322	}
323#include "swrast/s_linetemp.h"
324
325
326
327/*
328 * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage.
329 */
330#define NAME flat_8A8B8G8R_z_line
331#define SETUP_CODE						\
332   GET_XRB(xrb);						\
333   const GLubyte *color = vert1->color;				\
334   GLuint pixel = PACK_8A8B8G8R(color[0], color[1], color[2], color[3]);
335#define INTERP_Z 1
336#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
337#define PIXEL_TYPE GLuint
338#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
339#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y)
340#define CLIP_HACK 1
341#define PLOT(X,Y)		\
342	if (Z < *zPtr) {	\
343	   *zPtr = Z;		\
344	   *pixelPtr = pixel;	\
345	}
346#include "swrast/s_linetemp.h"
347
348
349
350/*
351 * Draw a flat-shaded, Z-less, PF_8A8R8G8B line into an XImage.
352 */
353#define NAME flat_8A8R8G8B_z_line
354#define SETUP_CODE						\
355   GET_XRB(xrb);						\
356   const GLubyte *color = vert1->color;				\
357   GLuint pixel = PACK_8A8R8G8B(color[0], color[1], color[2], color[3]);
358#define INTERP_Z 1
359#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
360#define PIXEL_TYPE GLuint
361#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
362#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y)
363#define CLIP_HACK 1
364#define PLOT(X,Y)		\
365	if (Z < *zPtr) {	\
366	   *zPtr = Z;		\
367	   *pixelPtr = pixel;	\
368	}
369#include "swrast/s_linetemp.h"
370
371
372
373/*
374 * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage.
375 */
376#define NAME flat_8R8G8B_z_line
377#define SETUP_CODE						\
378   GET_XRB(xrb);						\
379   const GLubyte *color = vert1->color;				\
380   GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
381#define INTERP_Z 1
382#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
383#define PIXEL_TYPE GLuint
384#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
385#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y)
386#define CLIP_HACK 1
387#define PLOT(X,Y)		\
388	if (Z < *zPtr) {	\
389	   *zPtr = Z;		\
390	   *pixelPtr = pixel;	\
391	}
392#include "swrast/s_linetemp.h"
393
394
395
396/*
397 * Draw a flat-shaded, Z-less, PF_8R8G8B24 line into an XImage.
398 */
399#define NAME flat_8R8G8B24_z_line
400#define SETUP_CODE						\
401   GET_XRB(xrb);						\
402   const GLubyte *color = vert1->color;
403#define INTERP_Z 1
404#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
405#define PIXEL_TYPE bgr_t
406#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
407#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X,Y)
408#define CLIP_HACK 1
409#define PLOT(X,Y)			\
410	if (Z < *zPtr) {		\
411	   *zPtr = Z;			\
412           pixelPtr->r = color[RCOMP];	\
413           pixelPtr->g = color[GCOMP];	\
414           pixelPtr->b = color[BCOMP];	\
415	}
416#include "swrast/s_linetemp.h"
417
418
419
420/*
421 * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage.
422 */
423#define NAME flat_5R6G5B_z_line
424#define SETUP_CODE						\
425   GET_XRB(xrb);						\
426   const GLubyte *color = vert1->color;				\
427   GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
428#define INTERP_Z 1
429#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
430#define PIXEL_TYPE GLushort
431#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
432#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X,Y)
433#define CLIP_HACK 1
434#define PLOT(X,Y)		\
435	if (Z < *zPtr) {	\
436	   *zPtr = Z;		\
437	   *pixelPtr = pixel;	\
438	}
439#include "swrast/s_linetemp.h"
440
441
442
443/*
444 * Draw a flat-shaded, Z-less, PF_DITHER_5R6G5B line into an XImage.
445 */
446#define NAME flat_DITHER_5R6G5B_z_line
447#define SETUP_CODE					\
448   GET_XRB(xrb);						\
449   XMesaContext xmesa = XMESA_CONTEXT(ctx);		\
450   const GLubyte *color = vert1->color;
451#define INTERP_Z 1
452#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
453#define PIXEL_TYPE GLushort
454#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
455#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X,Y)
456#define CLIP_HACK 1
457#define PLOT(X,Y)		\
458	if (Z < *zPtr) {	\
459	   *zPtr = Z;		\
460	   PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \
461	}
462#include "swrast/s_linetemp.h"
463
464
465
466/*
467 * Draw a flat-shaded, Z-less, PF_DITHER 8-bit line into an XImage.
468 */
469#define NAME flat_DITHER8_z_line
470#define SETUP_CODE					\
471   GET_XRB(xrb);						\
472   const GLubyte *color = vert1->color;			\
473   GLint r = color[0], g = color[1], b = color[2];	\
474   DITHER_SETUP;
475#define INTERP_Z 1
476#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
477#define PIXEL_TYPE GLubyte
478#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
479#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y)
480#define CLIP_HACK 1
481#define PLOT(X,Y)						\
482	if (Z < *zPtr) {					\
483	   *zPtr = Z;						\
484	   *pixelPtr = (GLubyte) DITHER( X, Y, r, g, b);	\
485	}
486#include "swrast/s_linetemp.h"
487
488
489
490/*
491 * Draw a flat-shaded, Z-less, PF_LOOKUP 8-bit line into an XImage.
492 */
493#define NAME flat_LOOKUP8_z_line
494#define SETUP_CODE						\
495   GET_XRB(xrb);						\
496   const GLubyte *color = vert1->color;				\
497   GLubyte pixel;						\
498   LOOKUP_SETUP;						\
499   pixel = (GLubyte) LOOKUP( color[0], color[1], color[2] );
500#define INTERP_Z 1
501#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
502#define PIXEL_TYPE GLubyte
503#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
504#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y)
505#define CLIP_HACK 1
506#define PLOT(X,Y)		\
507	if (Z < *zPtr) {	\
508	   *zPtr = Z;		\
509	   *pixelPtr = pixel;	\
510	}
511#include "swrast/s_linetemp.h"
512
513
514
515/*
516 * Draw a flat-shaded, Z-less, PF_HPCR line into an XImage.
517 */
518#define NAME flat_HPCR_z_line
519#define SETUP_CODE 						\
520   GET_XRB(xrb);						\
521   XMesaContext xmesa = XMESA_CONTEXT(ctx);			\
522   const GLubyte *color = vert1->color;				\
523   GLint r = color[0], g = color[1], b = color[2];
524#define INTERP_Z 1
525#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
526#define PIXEL_TYPE GLubyte
527#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
528#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y)
529#define CLIP_HACK 1
530#define PLOT(X,Y)						\
531	if (Z < *zPtr) {					\
532	   *zPtr = Z;						\
533	   *pixelPtr = (GLubyte) DITHER_HPCR( X, Y, r, g, b);	\
534	}
535#include "swrast/s_linetemp.h"
536
537
538
539
540#ifndef XFree86Server
541/**
542 * Draw fast, XOR line with XDrawLine in front color buffer.
543 * WARNING: this isn't fully OpenGL conformant because different pixels
544 * will be hit versus using the other line functions.
545 * Don't use the code in X server GLcore module since we need a wrapper
546 * for the XSetLineAttributes() function call.
547 */
548static void
549xor_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1)
550{
551   XMesaContext xmesa = XMESA_CONTEXT(ctx);
552   XMesaDisplay *dpy = xmesa->xm_visual->display;
553   XMesaGC gc = xmesa->xm_buffer->gc;
554   GET_XRB(xrb);
555   unsigned long pixel = xmesa_color_to_pixel(ctx,
556                                              vert1->color[0], vert1->color[1],
557                                              vert1->color[2], vert1->color[3],
558                                              xmesa->pixelformat);
559   int x0 = (int) vert0->win[0];
560   int y0 = YFLIP(xrb, (GLint) vert0->win[1]);
561   int x1 = (int) vert1->win[0];
562   int y1 = YFLIP(xrb, (GLint) vert1->win[1]);
563   XMesaSetForeground(dpy, gc, pixel);
564   XMesaSetFunction(dpy, gc, GXxor);
565   XSetLineAttributes(dpy, gc, (int) ctx->Line.Width,
566                      LineSolid, CapButt, JoinMiter);
567   XDrawLine(dpy, xrb->pixmap, gc, x0, y0, x1, y1);
568   XMesaSetFunction(dpy, gc, GXcopy);  /* this gc is used elsewhere */
569}
570#endif /* XFree86Server */
571
572
573#endif /* CHAN_BITS == 8 */
574
575
576/**
577 * Return pointer to line drawing function, or NULL if we should use a
578 * swrast fallback.
579 */
580static swrast_line_func
581get_line_func(GLcontext *ctx)
582{
583#if CHAN_BITS == 8
584   SWcontext *swrast = SWRAST_CONTEXT(ctx);
585   XMesaContext xmesa = XMESA_CONTEXT(ctx);
586   XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
587   const int depth = GET_VISUAL_DEPTH(xmesa->xm_visual);
588   const struct xmesa_renderbuffer *xrb;
589
590   if ((ctx->DrawBuffer->_ColorDrawBufferMask[0]
591        & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) == 0)
592      return (swrast_line_func) NULL;
593   if (ctx->RenderMode != GL_RENDER)      return (swrast_line_func) NULL;
594   if (ctx->Line.SmoothFlag)              return (swrast_line_func) NULL;
595   if (ctx->Texture._EnabledUnits)        return (swrast_line_func) NULL;
596   if (ctx->Light.ShadeModel != GL_FLAT)  return (swrast_line_func) NULL;
597   if (ctx->Line.StippleFlag)             return (swrast_line_func) NULL;
598   if (swrast->_RasterMask & MULTI_DRAW_BIT) return (swrast_line_func) NULL;
599   if (xmbuf->swAlpha)                    return (swrast_line_func) NULL;
600
601   xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
602
603   if (xrb->ximage
604       && swrast->_RasterMask==DEPTH_BIT
605       && ctx->Depth.Func==GL_LESS
606       && ctx->Depth.Mask==GL_TRUE
607       && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
608       && ctx->Line.Width==1.0F) {
609      switch (xmesa->pixelformat) {
610         case PF_Truecolor:
611            return flat_TRUECOLOR_z_line;
612         case PF_8A8B8G8R:
613            return flat_8A8B8G8R_z_line;
614         case PF_8A8R8G8B:
615            return flat_8A8R8G8B_z_line;
616         case PF_8R8G8B:
617            return flat_8R8G8B_z_line;
618         case PF_8R8G8B24:
619            return flat_8R8G8B24_z_line;
620         case PF_5R6G5B:
621            return flat_5R6G5B_z_line;
622         case PF_Dither_5R6G5B:
623            return flat_DITHER_5R6G5B_z_line;
624         case PF_Dither:
625            return (depth==8) ? flat_DITHER8_z_line : (swrast_line_func) NULL;
626         case PF_Lookup:
627            return (depth==8) ? flat_LOOKUP8_z_line : (swrast_line_func) NULL;
628         case PF_HPCR:
629            return flat_HPCR_z_line;
630         default:
631            return (swrast_line_func)NULL;
632      }
633   }
634   if (xrb->ximage
635       && swrast->_RasterMask==0
636       && ctx->Line.Width==1.0F) {
637      switch (xmesa->pixelformat) {
638         case PF_Truecolor:
639            return flat_TRUECOLOR_line;
640         case PF_8A8B8G8R:
641            return flat_8A8B8G8R_line;
642         case PF_8A8R8G8B:
643            return flat_8A8R8G8B_line;
644         case PF_8R8G8B:
645            return flat_8R8G8B_line;
646         case PF_8R8G8B24:
647            return flat_8R8G8B24_line;
648         case PF_5R6G5B:
649            return flat_5R6G5B_line;
650         case PF_Dither_5R6G5B:
651            return flat_DITHER_5R6G5B_line;
652         case PF_Dither:
653            return (depth==8) ? flat_DITHER8_line : (swrast_line_func) NULL;
654         case PF_Lookup:
655            return (depth==8) ? flat_LOOKUP8_line : (swrast_line_func) NULL;
656         case PF_HPCR:
657            return flat_HPCR_line;
658	 default:
659	    return (swrast_line_func)NULL;
660      }
661   }
662
663#ifndef XFree86Server
664   if (ctx->DrawBuffer->_NumColorDrawBuffers[0] == 1
665       && ctx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT
666       && swrast->_RasterMask == LOGIC_OP_BIT
667       && ctx->Color.LogicOp == GL_XOR
668       && !ctx->Line.StippleFlag
669       && !ctx->Line.SmoothFlag) {
670      return xor_line;
671   }
672#endif /* XFree86Server */
673
674#endif /* CHAN_BITS == 8 */
675   return (swrast_line_func) NULL;
676}
677
678
679/**
680 * Override for the swrast line-selection function.  Try to use one
681 * of our internal line functions, otherwise fall back to the
682 * standard swrast functions.
683 */
684void
685xmesa_choose_line(GLcontext *ctx)
686{
687   SWcontext *swrast = SWRAST_CONTEXT(ctx);
688
689   if (!(swrast->Line = get_line_func( ctx )))
690      _swrast_choose_line( ctx );
691}
692