1848b8605Smrg/*
2848b8605Smrg * Mesa 3-D graphics library
3848b8605Smrg *
4848b8605Smrg * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the "Software"),
8848b8605Smrg * to deal in the Software without restriction, including without limitation
9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
11848b8605Smrg * Software is furnished to do so, subject to the following conditions:
12848b8605Smrg *
13848b8605Smrg * The above copyright notice and this permission notice shall be included
14848b8605Smrg * in all copies or substantial portions of the Software.
15848b8605Smrg *
16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE.
23848b8605Smrg */
24848b8605Smrg
25848b8605Smrg
26848b8605Smrg/*
27848b8605Smrg * This file contains "accelerated" point, line, and triangle functions.
28848b8605Smrg * It should be fairly easy to write new special-purpose point, line or
29848b8605Smrg * triangle functions and hook them into this module.
30848b8605Smrg */
31848b8605Smrg
32848b8605Smrg
33848b8605Smrg#include "glxheader.h"
34848b8605Smrg#include "main/macros.h"
35848b8605Smrg#include "main/mtypes.h"
36848b8605Smrg#include "xmesaP.h"
37848b8605Smrg
38848b8605Smrg/* Internal swrast includes:
39848b8605Smrg */
40848b8605Smrg#include "swrast/s_depth.h"
41848b8605Smrg#include "swrast/s_points.h"
42848b8605Smrg#include "swrast/s_lines.h"
43848b8605Smrg#include "swrast/s_context.h"
44848b8605Smrg
45848b8605Smrg
46848b8605Smrg/**********************************************************************/
47848b8605Smrg/***                    Point rendering                             ***/
48848b8605Smrg/**********************************************************************/
49848b8605Smrg
50848b8605Smrg
51848b8605Smrg/*
52848b8605Smrg * Render an array of points into a pixmap, any pixel format.
53848b8605Smrg */
54848b8605Smrg#if 000
55848b8605Smrg/* XXX don't use this, it doesn't dither correctly */
56848b8605Smrgstatic void draw_points_ANY_pixmap( struct gl_context *ctx, const SWvertex *vert )
57848b8605Smrg{
58848b8605Smrg   XMesaContext xmesa = XMESA_CONTEXT(ctx);
59848b8605Smrg   XMesaDisplay *dpy = xmesa->xm_visual->display;
60848b8605Smrg   XMesaDrawable buffer = xmesa->xm_buffer->buffer;
61848b8605Smrg   XMesaGC gc = xmesa->xm_buffer->gc;
62848b8605Smrg
63848b8605Smrg   if (xmesa->xm_visual->mesa_visual.RGBAflag) {
64848b8605Smrg      register int x, y;
65848b8605Smrg      const GLubyte *color = vert->color;
66848b8605Smrg      unsigned long pixel = xmesa_color_to_pixel( xmesa,
67848b8605Smrg						  color[0], color[1],
68848b8605Smrg						  color[2], color[3],
69848b8605Smrg						  xmesa->pixelformat);
70848b8605Smrg      XMesaSetForeground( dpy, gc, pixel );
71848b8605Smrg      x = (GLint) vert->win[0];
72848b8605Smrg      y = YFLIP( xrb, (GLint) vert->win[1] );
73848b8605Smrg      XMesaDrawPoint( dpy, buffer, gc, x, y);
74848b8605Smrg   }
75848b8605Smrg   else {
76848b8605Smrg      /* Color index mode */
77848b8605Smrg      register int x, y;
78848b8605Smrg      XMesaSetForeground( dpy, gc, vert->index );
79848b8605Smrg      x =                         (GLint) vert->win[0];
80848b8605Smrg      y = YFLIP( xrb, (GLint) vert->win[1] );
81848b8605Smrg      XMesaDrawPoint( dpy, buffer, gc, x, y);
82848b8605Smrg   }
83848b8605Smrg}
84848b8605Smrg#endif
85848b8605Smrg
86848b8605Smrg
87848b8605Smrg/* Override the swrast point-selection function.  Try to use one of
88848b8605Smrg * our internal point functions, otherwise fall back to the standard
89848b8605Smrg * swrast functions.
90848b8605Smrg */
91848b8605Smrgvoid xmesa_choose_point( struct gl_context *ctx )
92848b8605Smrg{
93848b8605Smrg#if 0
94848b8605Smrg   XMesaContext xmesa = XMESA_CONTEXT(ctx);
95848b8605Smrg   SWcontext *swrast = SWRAST_CONTEXT(ctx);
96848b8605Smrg
97848b8605Smrg   if (ctx->RenderMode == GL_RENDER
98848b8605Smrg       && ctx->Point.Size == 1.0F && !ctx->Point.SmoothFlag
99848b8605Smrg       && swrast->_RasterMask == 0
100848b8605Smrg       && ctx->Texture._MaxEnabledTexImageUnit == -1
101848b8605Smrg       && xmesa->xm_buffer->buffer != XIMAGE) {
102848b8605Smrg      swrast->Point = draw_points_ANY_pixmap;
103848b8605Smrg   }
104848b8605Smrg   else {
105848b8605Smrg      _swrast_choose_point( ctx );
106848b8605Smrg   }
107848b8605Smrg#else
108848b8605Smrg   _swrast_choose_point( ctx );
109848b8605Smrg#endif
110848b8605Smrg}
111848b8605Smrg
112848b8605Smrg
113848b8605Smrg
114848b8605Smrg/**********************************************************************/
115848b8605Smrg/***                      Line rendering                            ***/
116848b8605Smrg/**********************************************************************/
117848b8605Smrg
118848b8605Smrg
119848b8605Smrg#if CHAN_BITS == 8
120848b8605Smrg
121848b8605Smrg
122848b8605Smrg#define GET_XRB(XRB)  struct xmesa_renderbuffer *XRB = \
123848b8605Smrg   xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0])
124848b8605Smrg
125848b8605Smrg
126848b8605Smrg/*
127848b8605Smrg * Draw a flat-shaded, PF_TRUECOLOR line into an XImage.
128848b8605Smrg */
129848b8605Smrg#define NAME flat_TRUECOLOR_line
130848b8605Smrg#define SETUP_CODE					\
131848b8605Smrg   XMesaContext xmesa = XMESA_CONTEXT(ctx);		\
132848b8605Smrg   GET_XRB(xrb);					\
133848b8605Smrg   const GLubyte *color = vert1->color;			\
134848b8605Smrg   unsigned long pixel;					\
135848b8605Smrg   PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
136848b8605Smrg#define CLIP_HACK 1
137848b8605Smrg#define PLOT(X,Y) XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel );
138848b8605Smrg#include "swrast/s_linetemp.h"
139848b8605Smrg
140848b8605Smrg
141848b8605Smrg
142848b8605Smrg/*
143848b8605Smrg * Draw a flat-shaded, PF_8A8B8G8R line into an XImage.
144848b8605Smrg */
145848b8605Smrg#define NAME flat_8A8B8G8R_line
146848b8605Smrg#define SETUP_CODE						\
147848b8605Smrg   GET_XRB(xrb);						\
148848b8605Smrg   const GLubyte *color = vert1->color;				\
149848b8605Smrg   GLuint pixel = PACK_8A8B8G8R(color[0], color[1], color[2], color[3]);
150848b8605Smrg#define PIXEL_TYPE GLuint
151848b8605Smrg#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
152848b8605Smrg#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
153848b8605Smrg#define CLIP_HACK 1
154848b8605Smrg#define PLOT(X,Y) *pixelPtr = pixel;
155848b8605Smrg#include "swrast/s_linetemp.h"
156848b8605Smrg
157848b8605Smrg
158848b8605Smrg
159848b8605Smrg/*
160848b8605Smrg * Draw a flat-shaded, PF_8A8R8G8B line into an XImage.
161848b8605Smrg */
162848b8605Smrg#define NAME flat_8A8R8G8B_line
163848b8605Smrg#define SETUP_CODE						\
164848b8605Smrg   GET_XRB(xrb);						\
165848b8605Smrg   const GLubyte *color = vert1->color;				\
166848b8605Smrg   GLuint pixel = PACK_8A8R8G8B(color[0], color[1], color[2], color[3]);
167848b8605Smrg#define PIXEL_TYPE GLuint
168848b8605Smrg#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
169848b8605Smrg#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
170848b8605Smrg#define CLIP_HACK 1
171848b8605Smrg#define PLOT(X,Y) *pixelPtr = pixel;
172848b8605Smrg#include "swrast/s_linetemp.h"
173848b8605Smrg
174848b8605Smrg
175848b8605Smrg
176848b8605Smrg/*
177848b8605Smrg * Draw a flat-shaded, PF_8R8G8B line into an XImage.
178848b8605Smrg */
179848b8605Smrg#define NAME flat_8R8G8B_line
180848b8605Smrg#define SETUP_CODE						\
181848b8605Smrg   GET_XRB(xrb);						\
182848b8605Smrg   const GLubyte *color = vert1->color;				\
183848b8605Smrg   GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
184848b8605Smrg#define PIXEL_TYPE GLuint
185848b8605Smrg#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
186848b8605Smrg#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
187848b8605Smrg#define CLIP_HACK 1
188848b8605Smrg#define PLOT(X,Y) *pixelPtr = pixel;
189848b8605Smrg#include "swrast/s_linetemp.h"
190848b8605Smrg
191848b8605Smrg
192848b8605Smrg
193848b8605Smrg/*
194848b8605Smrg * Draw a flat-shaded, PF_8R8G8B24 line into an XImage.
195848b8605Smrg */
196848b8605Smrg#define NAME flat_8R8G8B24_line
197848b8605Smrg#define SETUP_CODE						\
198848b8605Smrg   GET_XRB(xrb);						\
199848b8605Smrg   const GLubyte *color = vert1->color;
200848b8605Smrg#define PIXEL_TYPE bgr_t
201848b8605Smrg#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
202848b8605Smrg#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y)
203848b8605Smrg#define CLIP_HACK 1
204848b8605Smrg#define PLOT(X,Y) {			\
205848b8605Smrg      pixelPtr->r = color[RCOMP];	\
206848b8605Smrg      pixelPtr->g = color[GCOMP];	\
207848b8605Smrg      pixelPtr->b = color[BCOMP];	\
208848b8605Smrg}
209848b8605Smrg#include "swrast/s_linetemp.h"
210848b8605Smrg
211848b8605Smrg
212848b8605Smrg
213848b8605Smrg/*
214848b8605Smrg * Draw a flat-shaded, PF_5R6G5B line into an XImage.
215848b8605Smrg */
216848b8605Smrg#define NAME flat_5R6G5B_line
217848b8605Smrg#define SETUP_CODE						\
218848b8605Smrg   GET_XRB(xrb);						\
219848b8605Smrg   const GLubyte *color = vert1->color;				\
220848b8605Smrg   GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
221848b8605Smrg#define PIXEL_TYPE GLushort
222848b8605Smrg#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
223848b8605Smrg#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
224848b8605Smrg#define CLIP_HACK 1
225848b8605Smrg#define PLOT(X,Y) *pixelPtr = pixel;
226848b8605Smrg#include "swrast/s_linetemp.h"
227848b8605Smrg
228848b8605Smrg
229848b8605Smrg
230848b8605Smrg/*
231848b8605Smrg * Draw a flat-shaded, PF_DITHER_5R6G5B line into an XImage.
232848b8605Smrg */
233848b8605Smrg#define NAME flat_DITHER_5R6G5B_line
234848b8605Smrg#define SETUP_CODE						\
235848b8605Smrg   GET_XRB(xrb);						\
236848b8605Smrg   XMesaContext xmesa = XMESA_CONTEXT(ctx);			\
237848b8605Smrg   const GLubyte *color = vert1->color;
238848b8605Smrg#define PIXEL_TYPE GLushort
239848b8605Smrg#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
240848b8605Smrg#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
241848b8605Smrg#define CLIP_HACK 1
242848b8605Smrg#define PLOT(X,Y) PACK_TRUEDITHER( *pixelPtr, X, Y, color[0], color[1], color[2] );
243848b8605Smrg#include "swrast/s_linetemp.h"
244848b8605Smrg
245848b8605Smrg
246848b8605Smrg
247848b8605Smrg/*
248848b8605Smrg * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage.
249848b8605Smrg */
250848b8605Smrg#define NAME flat_TRUECOLOR_z_line
251848b8605Smrg#define SETUP_CODE						\
252848b8605Smrg   GET_XRB(xrb);						\
253848b8605Smrg   XMesaContext xmesa = XMESA_CONTEXT(ctx);			\
254848b8605Smrg   const GLubyte *color = vert1->color;				\
255848b8605Smrg   unsigned long pixel;						\
256848b8605Smrg   PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
257848b8605Smrg#define INTERP_Z 1
258848b8605Smrg#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
259848b8605Smrg#define CLIP_HACK 1
260848b8605Smrg#define PLOT(X,Y)							\
261848b8605Smrg	if (Z < *zPtr) {						\
262848b8605Smrg	   *zPtr = Z;							\
263848b8605Smrg           XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel);		\
264848b8605Smrg	}
265848b8605Smrg#include "swrast/s_linetemp.h"
266848b8605Smrg
267848b8605Smrg
268848b8605Smrg
269848b8605Smrg/*
270848b8605Smrg * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage.
271848b8605Smrg */
272848b8605Smrg#define NAME flat_8A8B8G8R_z_line
273848b8605Smrg#define SETUP_CODE						\
274848b8605Smrg   GET_XRB(xrb);						\
275848b8605Smrg   const GLubyte *color = vert1->color;				\
276848b8605Smrg   GLuint pixel = PACK_8A8B8G8R(color[0], color[1], color[2], color[3]);
277848b8605Smrg#define INTERP_Z 1
278848b8605Smrg#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
279848b8605Smrg#define PIXEL_TYPE GLuint
280848b8605Smrg#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
281848b8605Smrg#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y)
282848b8605Smrg#define CLIP_HACK 1
283848b8605Smrg#define PLOT(X,Y)		\
284848b8605Smrg	if (Z < *zPtr) {	\
285848b8605Smrg	   *zPtr = Z;		\
286848b8605Smrg	   *pixelPtr = pixel;	\
287848b8605Smrg	}
288848b8605Smrg#include "swrast/s_linetemp.h"
289848b8605Smrg
290848b8605Smrg
291848b8605Smrg
292848b8605Smrg/*
293848b8605Smrg * Draw a flat-shaded, Z-less, PF_8A8R8G8B line into an XImage.
294848b8605Smrg */
295848b8605Smrg#define NAME flat_8A8R8G8B_z_line
296848b8605Smrg#define SETUP_CODE						\
297848b8605Smrg   GET_XRB(xrb);						\
298848b8605Smrg   const GLubyte *color = vert1->color;				\
299848b8605Smrg   GLuint pixel = PACK_8A8R8G8B(color[0], color[1], color[2], color[3]);
300848b8605Smrg#define INTERP_Z 1
301848b8605Smrg#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
302848b8605Smrg#define PIXEL_TYPE GLuint
303848b8605Smrg#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
304848b8605Smrg#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y)
305848b8605Smrg#define CLIP_HACK 1
306848b8605Smrg#define PLOT(X,Y)		\
307848b8605Smrg	if (Z < *zPtr) {	\
308848b8605Smrg	   *zPtr = Z;		\
309848b8605Smrg	   *pixelPtr = pixel;	\
310848b8605Smrg	}
311848b8605Smrg#include "swrast/s_linetemp.h"
312848b8605Smrg
313848b8605Smrg
314848b8605Smrg
315848b8605Smrg/*
316848b8605Smrg * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage.
317848b8605Smrg */
318848b8605Smrg#define NAME flat_8R8G8B_z_line
319848b8605Smrg#define SETUP_CODE						\
320848b8605Smrg   GET_XRB(xrb);						\
321848b8605Smrg   const GLubyte *color = vert1->color;				\
322848b8605Smrg   GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
323848b8605Smrg#define INTERP_Z 1
324848b8605Smrg#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
325848b8605Smrg#define PIXEL_TYPE GLuint
326848b8605Smrg#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
327848b8605Smrg#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y)
328848b8605Smrg#define CLIP_HACK 1
329848b8605Smrg#define PLOT(X,Y)		\
330848b8605Smrg	if (Z < *zPtr) {	\
331848b8605Smrg	   *zPtr = Z;		\
332848b8605Smrg	   *pixelPtr = pixel;	\
333848b8605Smrg	}
334848b8605Smrg#include "swrast/s_linetemp.h"
335848b8605Smrg
336848b8605Smrg
337848b8605Smrg
338848b8605Smrg/*
339848b8605Smrg * Draw a flat-shaded, Z-less, PF_8R8G8B24 line into an XImage.
340848b8605Smrg */
341848b8605Smrg#define NAME flat_8R8G8B24_z_line
342848b8605Smrg#define SETUP_CODE						\
343848b8605Smrg   GET_XRB(xrb);						\
344848b8605Smrg   const GLubyte *color = vert1->color;
345848b8605Smrg#define INTERP_Z 1
346848b8605Smrg#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
347848b8605Smrg#define PIXEL_TYPE bgr_t
348848b8605Smrg#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
349848b8605Smrg#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X,Y)
350848b8605Smrg#define CLIP_HACK 1
351848b8605Smrg#define PLOT(X,Y)			\
352848b8605Smrg	if (Z < *zPtr) {		\
353848b8605Smrg	   *zPtr = Z;			\
354848b8605Smrg           pixelPtr->r = color[RCOMP];	\
355848b8605Smrg           pixelPtr->g = color[GCOMP];	\
356848b8605Smrg           pixelPtr->b = color[BCOMP];	\
357848b8605Smrg	}
358848b8605Smrg#include "swrast/s_linetemp.h"
359848b8605Smrg
360848b8605Smrg
361848b8605Smrg
362848b8605Smrg/*
363848b8605Smrg * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage.
364848b8605Smrg */
365848b8605Smrg#define NAME flat_5R6G5B_z_line
366848b8605Smrg#define SETUP_CODE						\
367848b8605Smrg   GET_XRB(xrb);						\
368848b8605Smrg   const GLubyte *color = vert1->color;				\
369848b8605Smrg   GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
370848b8605Smrg#define INTERP_Z 1
371848b8605Smrg#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
372848b8605Smrg#define PIXEL_TYPE GLushort
373848b8605Smrg#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
374848b8605Smrg#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X,Y)
375848b8605Smrg#define CLIP_HACK 1
376848b8605Smrg#define PLOT(X,Y)		\
377848b8605Smrg	if (Z < *zPtr) {	\
378848b8605Smrg	   *zPtr = Z;		\
379848b8605Smrg	   *pixelPtr = pixel;	\
380848b8605Smrg	}
381848b8605Smrg#include "swrast/s_linetemp.h"
382848b8605Smrg
383848b8605Smrg
384848b8605Smrg
385848b8605Smrg/*
386848b8605Smrg * Draw a flat-shaded, Z-less, PF_DITHER_5R6G5B line into an XImage.
387848b8605Smrg */
388848b8605Smrg#define NAME flat_DITHER_5R6G5B_z_line
389848b8605Smrg#define SETUP_CODE					\
390848b8605Smrg   GET_XRB(xrb);						\
391848b8605Smrg   XMesaContext xmesa = XMESA_CONTEXT(ctx);		\
392848b8605Smrg   const GLubyte *color = vert1->color;
393848b8605Smrg#define INTERP_Z 1
394848b8605Smrg#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
395848b8605Smrg#define PIXEL_TYPE GLushort
396848b8605Smrg#define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
397848b8605Smrg#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X,Y)
398848b8605Smrg#define CLIP_HACK 1
399848b8605Smrg#define PLOT(X,Y)		\
400848b8605Smrg	if (Z < *zPtr) {	\
401848b8605Smrg	   *zPtr = Z;		\
402848b8605Smrg	   PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \
403848b8605Smrg	}
404848b8605Smrg#include "swrast/s_linetemp.h"
405848b8605Smrg
406848b8605Smrg
407848b8605Smrg
408848b8605Smrg/**
409848b8605Smrg * Draw fast, XOR line with XDrawLine in front color buffer.
410848b8605Smrg * WARNING: this isn't fully OpenGL conformant because different pixels
411848b8605Smrg * will be hit versus using the other line functions.
412848b8605Smrg * Don't use the code in X server GLcore module since we need a wrapper
413848b8605Smrg * for the XSetLineAttributes() function call.
414848b8605Smrg */
415848b8605Smrgstatic void
416848b8605Smrgxor_line(struct gl_context *ctx, const SWvertex *vert0, const SWvertex *vert1)
417848b8605Smrg{
418848b8605Smrg   XMesaContext xmesa = XMESA_CONTEXT(ctx);
419848b8605Smrg   XMesaDisplay *dpy = xmesa->xm_visual->display;
420848b8605Smrg   XMesaGC gc = xmesa->xm_buffer->gc;
421848b8605Smrg   GET_XRB(xrb);
422848b8605Smrg   unsigned long pixel = xmesa_color_to_pixel(ctx,
423848b8605Smrg                                              vert1->color[0], vert1->color[1],
424848b8605Smrg                                              vert1->color[2], vert1->color[3],
425848b8605Smrg                                              xmesa->pixelformat);
426848b8605Smrg   int x0 =            (GLint) vert0->attrib[VARYING_SLOT_POS][0];
427848b8605Smrg   int y0 = YFLIP(xrb, (GLint) vert0->attrib[VARYING_SLOT_POS][1]);
428848b8605Smrg   int x1 =            (GLint) vert1->attrib[VARYING_SLOT_POS][0];
429848b8605Smrg   int y1 = YFLIP(xrb, (GLint) vert1->attrib[VARYING_SLOT_POS][1]);
430848b8605Smrg   XMesaSetForeground(dpy, gc, pixel);
431848b8605Smrg   XMesaSetFunction(dpy, gc, GXxor);
432848b8605Smrg   XSetLineAttributes(dpy, gc, (int) ctx->Line.Width,
433848b8605Smrg                      LineSolid, CapButt, JoinMiter);
434848b8605Smrg   XDrawLine(dpy, xrb->pixmap, gc, x0, y0, x1, y1);
435848b8605Smrg   XMesaSetFunction(dpy, gc, GXcopy);  /* this gc is used elsewhere */
436848b8605Smrg}
437848b8605Smrg
438848b8605Smrg
439848b8605Smrg#endif /* CHAN_BITS == 8 */
440848b8605Smrg
441848b8605Smrg
442848b8605Smrg/**
443848b8605Smrg * Return pointer to line drawing function, or NULL if we should use a
444848b8605Smrg * swrast fallback.
445848b8605Smrg */
446848b8605Smrgstatic swrast_line_func
447848b8605Smrgget_line_func(struct gl_context *ctx)
448848b8605Smrg{
449848b8605Smrg#if CHAN_BITS == 8
450848b8605Smrg   SWcontext *swrast = SWRAST_CONTEXT(ctx);
451848b8605Smrg   XMesaContext xmesa = XMESA_CONTEXT(ctx);
452848b8605Smrg   const struct xmesa_renderbuffer *xrb;
453848b8605Smrg
454848b8605Smrg   if ((ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_FRONT_LEFT) &&
455848b8605Smrg       (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_BACK_LEFT))
456848b8605Smrg      return (swrast_line_func) NULL;
457848b8605Smrg   if (ctx->RenderMode != GL_RENDER)      return (swrast_line_func) NULL;
458848b8605Smrg   if (ctx->Line.SmoothFlag)              return (swrast_line_func) NULL;
459848b8605Smrg   if (ctx->Texture._MaxEnabledTexImageUnit != -1)        return (swrast_line_func) NULL;
460848b8605Smrg   if (ctx->Light.ShadeModel != GL_FLAT)  return (swrast_line_func) NULL;
461848b8605Smrg   if (ctx->Line.StippleFlag)             return (swrast_line_func) NULL;
462848b8605Smrg   if (swrast->_RasterMask & MULTI_DRAW_BIT) return (swrast_line_func) NULL;
463848b8605Smrg
464848b8605Smrg   xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
465848b8605Smrg
466848b8605Smrg   if (xrb->ximage
467848b8605Smrg       && swrast->_RasterMask==DEPTH_BIT
468848b8605Smrg       && ctx->Depth.Func==GL_LESS
469848b8605Smrg       && ctx->Depth.Mask==GL_TRUE
470848b8605Smrg       && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
471848b8605Smrg       && ctx->Line.Width==1.0F) {
472848b8605Smrg      switch (xmesa->pixelformat) {
473848b8605Smrg         case PF_Truecolor:
474848b8605Smrg            return flat_TRUECOLOR_z_line;
475848b8605Smrg         case PF_8A8B8G8R:
476848b8605Smrg            return flat_8A8B8G8R_z_line;
477848b8605Smrg         case PF_8A8R8G8B:
478848b8605Smrg            return flat_8A8R8G8B_z_line;
479848b8605Smrg         case PF_8R8G8B:
480848b8605Smrg            return flat_8R8G8B_z_line;
481848b8605Smrg         case PF_8R8G8B24:
482848b8605Smrg            return flat_8R8G8B24_z_line;
483848b8605Smrg         case PF_5R6G5B:
484848b8605Smrg            return flat_5R6G5B_z_line;
485848b8605Smrg         case PF_Dither_5R6G5B:
486848b8605Smrg            return flat_DITHER_5R6G5B_z_line;
487848b8605Smrg         default:
488848b8605Smrg            return (swrast_line_func)NULL;
489848b8605Smrg      }
490848b8605Smrg   }
491848b8605Smrg   if (xrb->ximage
492848b8605Smrg       && swrast->_RasterMask==0
493848b8605Smrg       && ctx->Line.Width==1.0F) {
494848b8605Smrg      switch (xmesa->pixelformat) {
495848b8605Smrg         case PF_Truecolor:
496848b8605Smrg            return flat_TRUECOLOR_line;
497848b8605Smrg         case PF_8A8B8G8R:
498848b8605Smrg            return flat_8A8B8G8R_line;
499848b8605Smrg         case PF_8A8R8G8B:
500848b8605Smrg            return flat_8A8R8G8B_line;
501848b8605Smrg         case PF_8R8G8B:
502848b8605Smrg            return flat_8R8G8B_line;
503848b8605Smrg         case PF_8R8G8B24:
504848b8605Smrg            return flat_8R8G8B24_line;
505848b8605Smrg         case PF_5R6G5B:
506848b8605Smrg            return flat_5R6G5B_line;
507848b8605Smrg         case PF_Dither_5R6G5B:
508848b8605Smrg            return flat_DITHER_5R6G5B_line;
509848b8605Smrg	 default:
510848b8605Smrg	    return (swrast_line_func)NULL;
511848b8605Smrg      }
512848b8605Smrg   }
513848b8605Smrg
514848b8605Smrg   if (ctx->DrawBuffer->_NumColorDrawBuffers == 1
515848b8605Smrg       && ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT
516848b8605Smrg       && swrast->_RasterMask == LOGIC_OP_BIT
517848b8605Smrg       && ctx->Color.LogicOp == GL_XOR
518848b8605Smrg       && !ctx->Line.StippleFlag
519848b8605Smrg       && !ctx->Line.SmoothFlag) {
520848b8605Smrg      return xor_line;
521848b8605Smrg   }
522848b8605Smrg
523848b8605Smrg#endif /* CHAN_BITS == 8 */
524848b8605Smrg   return (swrast_line_func) NULL;
525848b8605Smrg}
526848b8605Smrg
527848b8605Smrg
528848b8605Smrg/**
529848b8605Smrg * Override for the swrast line-selection function.  Try to use one
530848b8605Smrg * of our internal line functions, otherwise fall back to the
531848b8605Smrg * standard swrast functions.
532848b8605Smrg */
533848b8605Smrgvoid
534848b8605Smrgxmesa_choose_line(struct gl_context *ctx)
535848b8605Smrg{
536848b8605Smrg   SWcontext *swrast = SWRAST_CONTEXT(ctx);
537848b8605Smrg
538848b8605Smrg   if (!(swrast->Line = get_line_func( ctx )))
539848b8605Smrg      _swrast_choose_line( ctx );
540848b8605Smrg}
541