Add a couple of helper functions for completeness.
[mesa.git] / src / mesa / drivers / glide / fxddspan.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 4.0
4 *
5 * Copyright (C) 1999-2001 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 /* Authors:
26 * David Bucciarelli
27 * Brian Paul
28 * Daryll Strauss
29 * Keith Whitwell
30 * Daniel Borca
31 * Hiroshi Morii
32 */
33
34
35 /* fxdd.c - 3Dfx VooDoo Mesa span and pixel functions */
36
37
38 #ifdef HAVE_CONFIG_H
39 #include "conf.h"
40 #endif
41
42 #if defined(FX)
43
44 #include "fxdrv.h"
45 #include "fxglidew.h"
46 #include "swrast/swrast.h"
47
48
49 /************************************************************************/
50 /***** Span functions *****/
51 /************************************************************************/
52
53 #define DBG 0
54
55
56 #define LOCAL_VARS \
57 GLuint pitch = info.strideInBytes; \
58 GLuint height = fxMesa->height; \
59 char *buf = (char *)((char *)info.lfbPtr + 0 /* x, y offset */); \
60 GLuint p; \
61 (void) buf; (void) p;
62
63 #define CLIPPIXEL( _x, _y ) ( _x >= minx && _x < maxx && \
64 _y >= miny && _y < maxy )
65
66 #define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
67 if ( _y < miny || _y >= maxy ) { \
68 _n1 = 0, _x1 = x; \
69 } else { \
70 _n1 = _n; \
71 _x1 = _x; \
72 if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx;\
73 if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \
74 }
75
76 #define Y_FLIP(_y) (height - _y - 1)
77
78 #define HW_WRITE_LOCK() \
79 fxMesaContext fxMesa = FX_CONTEXT(ctx); \
80 GrLfbInfo_t info; \
81 info.size = sizeof(GrLfbInfo_t); \
82 if ( grLfbLock( GR_LFB_WRITE_ONLY, \
83 fxMesa->currentFB, LFB_MODE, \
84 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) {
85
86 #define HW_WRITE_UNLOCK() \
87 grLfbUnlock( GR_LFB_WRITE_ONLY, fxMesa->currentFB ); \
88 }
89
90 #define HW_READ_LOCK() \
91 fxMesaContext fxMesa = FX_CONTEXT(ctx); \
92 GrLfbInfo_t info; \
93 info.size = sizeof(GrLfbInfo_t); \
94 if ( grLfbLock( GR_LFB_READ_ONLY, fxMesa->currentFB, \
95 LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) {
96
97 #define HW_READ_UNLOCK() \
98 grLfbUnlock( GR_LFB_READ_ONLY, fxMesa->currentFB ); \
99 }
100
101 #define HW_WRITE_CLIPLOOP() \
102 do { \
103 /* remember, we need to flip the scissor, too */ \
104 /* is it better to do it inside fxDDScissor? */ \
105 const int minx = fxMesa->clipMinX; \
106 const int maxy = Y_FLIP(fxMesa->clipMinY); \
107 const int maxx = fxMesa->clipMaxX; \
108 const int miny = Y_FLIP(fxMesa->clipMaxY);
109
110 #define HW_READ_CLIPLOOP() \
111 do { \
112 /* remember, we need to flip the scissor, too */ \
113 /* is it better to do it inside fxDDScissor? */ \
114 const int minx = fxMesa->clipMinX; \
115 const int maxy = Y_FLIP(fxMesa->clipMinY); \
116 const int maxx = fxMesa->clipMaxX; \
117 const int miny = Y_FLIP(fxMesa->clipMaxY);
118
119 #define HW_ENDCLIPLOOP() \
120 } while (0)
121
122
123 /* 16 bit, ARGB1555 color spanline and pixel functions */
124
125 #undef LFB_MODE
126 #define LFB_MODE GR_LFBWRITEMODE_1555
127
128 #undef BYTESPERPIXEL
129 #define BYTESPERPIXEL 2
130
131 #undef INIT_MONO_PIXEL
132 #define INIT_MONO_PIXEL(p, color) \
133 p = TDFXPACKCOLOR1555( color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP] )
134
135 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
136 *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = \
137 TDFXPACKCOLOR1555( r, g, b, a )
138
139 #define WRITE_PIXEL( _x, _y, p ) \
140 *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = p
141
142 #define READ_RGBA( rgba, _x, _y ) \
143 do { \
144 GLushort p = *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch); \
145 rgba[0] = FX_rgb_scale_5[(p >> 10) & 0x1F]; \
146 rgba[1] = FX_rgb_scale_5[(p >> 5) & 0x1F]; \
147 rgba[2] = FX_rgb_scale_5[ p & 0x1F]; \
148 rgba[3] = (p & 0x8000) ? 255 : 0; \
149 } while (0)
150
151 #define TAG(x) tdfx##x##_ARGB1555
152 #include "../dri/common/spantmp.h"
153
154
155 /* 16 bit, RGB565 color spanline and pixel functions */
156 /* [dBorca] Hack alert:
157 * This is wrong. The alpha value is lost, even when we provide
158 * HW alpha (565 w/o depth buffering). To really update alpha buffer,
159 * we would need to do the 565 writings via 8888 colorformat and rely
160 * on the Voodoo to perform color scaling. In which case our 565 span
161 * would look nicer! But this violates FSAA rules...
162 */
163
164 #undef LFB_MODE
165 #define LFB_MODE GR_LFBWRITEMODE_565
166
167 #undef BYTESPERPIXEL
168 #define BYTESPERPIXEL 2
169
170 #undef INIT_MONO_PIXEL
171 #define INIT_MONO_PIXEL(p, color) \
172 p = TDFXPACKCOLOR565( color[RCOMP], color[GCOMP], color[BCOMP] )
173
174 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
175 *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = \
176 TDFXPACKCOLOR565( r, g, b )
177
178 #define WRITE_PIXEL( _x, _y, p ) \
179 *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = p
180
181 #define READ_RGBA( rgba, _x, _y ) \
182 do { \
183 GLushort p = *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch); \
184 rgba[0] = FX_rgb_scale_5[(p >> 11) & 0x1F]; \
185 rgba[1] = FX_rgb_scale_6[(p >> 5) & 0x3F]; \
186 rgba[2] = FX_rgb_scale_5[ p & 0x1F]; \
187 rgba[3] = 0xff; \
188 } while (0)
189
190 #define TAG(x) tdfx##x##_RGB565
191 #include "../dri/common/spantmp.h"
192
193
194 /* 32 bit, ARGB8888 color spanline and pixel functions */
195
196 #undef LFB_MODE
197 #define LFB_MODE GR_LFBWRITEMODE_8888
198
199 #undef BYTESPERPIXEL
200 #define BYTESPERPIXEL 4
201
202 #undef INIT_MONO_PIXEL
203 #define INIT_MONO_PIXEL(p, color) \
204 p = TDFXPACKCOLOR8888( color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP] )
205
206 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
207 *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) = \
208 TDFXPACKCOLOR8888( r, g, b, a )
209
210 #define WRITE_PIXEL( _x, _y, p ) \
211 *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) = p
212
213 #define READ_RGBA( rgba, _x, _y ) \
214 do { \
215 GLuint p = *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch); \
216 rgba[0] = (p >> 16) & 0xff; \
217 rgba[1] = (p >> 8) & 0xff; \
218 rgba[2] = (p >> 0) & 0xff; \
219 rgba[3] = (p >> 24) & 0xff; \
220 } while (0)
221
222 #define TAG(x) tdfx##x##_ARGB8888
223 #include "../dri/common/spantmp.h"
224
225
226 /************************************************************************/
227 /***** Depth functions *****/
228 /************************************************************************/
229
230 #define DBG 0
231
232 #undef HW_WRITE_LOCK
233 #undef HW_WRITE_UNLOCK
234 #undef HW_READ_LOCK
235 #undef HW_READ_UNLOCK
236
237 #define HW_CLIPLOOP HW_WRITE_CLIPLOOP
238
239 #define LOCAL_DEPTH_VARS \
240 GLuint pitch = info.strideInBytes; \
241 GLuint height = fxMesa->height; \
242 char *buf = (char *)((char *)info.lfbPtr + 0 /* x, y offset */); \
243 (void) buf;
244
245 #define HW_WRITE_LOCK() \
246 fxMesaContext fxMesa = FX_CONTEXT(ctx); \
247 GrLfbInfo_t info; \
248 info.size = sizeof(GrLfbInfo_t); \
249 if ( grLfbLock( GR_LFB_WRITE_ONLY, \
250 GR_BUFFER_AUXBUFFER, LFB_MODE, \
251 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) {
252
253 #define HW_WRITE_UNLOCK() \
254 grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_AUXBUFFER); \
255 }
256
257 #define HW_READ_LOCK() \
258 fxMesaContext fxMesa = FX_CONTEXT(ctx); \
259 GrLfbInfo_t info; \
260 info.size = sizeof(GrLfbInfo_t); \
261 if ( grLfbLock( GR_LFB_READ_ONLY, GR_BUFFER_AUXBUFFER, \
262 LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) {
263
264 #define HW_READ_UNLOCK() \
265 grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_AUXBUFFER); \
266 }
267
268
269 /* 16 bit, depth spanline and pixel functions */
270
271 #undef LFB_MODE
272 #define LFB_MODE GR_LFBWRITEMODE_ZA16
273
274 #undef BYTESPERPIXEL
275 #define BYTESPERPIXEL 2
276
277 #define WRITE_DEPTH( _x, _y, d ) \
278 *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = d
279
280 #define READ_DEPTH( d, _x, _y ) \
281 d = *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch)
282
283 #define TAG(x) tdfx##x##_Z16
284 #include "../dri/common/depthtmp.h"
285
286
287 /* 24 bit, depth spanline and pixel functions (for use w/ stencil) */
288 /* [dBorca] Hack alert:
289 * This is evil. The incoming Mesa's 24bit depth value
290 * is shifted left 8 bits, to obtain a full 32bit value,
291 * which will be thrown into the framebuffer. We rely on
292 * the fact that Voodoo hardware transforms a 32bit value
293 * into 24bit value automatically and, MOST IMPORTANT, won't
294 * alter the upper 8bits of the value already existing in the
295 * framebuffer (where stencil resides).
296 */
297
298 #undef LFB_MODE
299 #define LFB_MODE GR_LFBWRITEMODE_Z32
300
301 #undef BYTESPERPIXEL
302 #define BYTESPERPIXEL 4
303
304 #define WRITE_DEPTH( _x, _y, d ) \
305 *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) = d << 8
306
307 #define READ_DEPTH( d, _x, _y ) \
308 d = (*(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch)) & 0xffffff
309
310 #define TAG(x) tdfx##x##_Z24
311 #include "../dri/common/depthtmp.h"
312
313
314 /* 32 bit, depth spanline and pixel functions (for use w/o stencil) */
315 /* [dBorca] Hack alert:
316 * This is more evil. We make Mesa run in 32bit depth, but
317 * tha Voodoo HW can only handle 24bit depth. Well, exploiting
318 * the pixel pipeline, we can achieve 24:8 format for greater
319 * precision...
320 * If anyone tells me how to really store 32bit values into the
321 * depth buffer, I'll write the *_Z32 routines. Howver, bear in
322 * mind that means running without stencil!
323 */
324
325 /************************************************************************/
326 /***** Span functions (optimized) *****/
327 /************************************************************************/
328
329 /*
330 * Read a span of 15-bit RGB pixels. Note, we don't worry about cliprects
331 * since OpenGL says obscured pixels have undefined values.
332 */
333 static void fxReadRGBASpan_ARGB1555 (const GLcontext * ctx,
334 GLuint n,
335 GLint x, GLint y,
336 GLubyte rgba[][4])
337 {
338 fxMesaContext fxMesa = FX_CONTEXT(ctx);
339 GrLfbInfo_t info;
340 info.size = sizeof(GrLfbInfo_t);
341 if (grLfbLock(GR_LFB_READ_ONLY, fxMesa->currentFB,
342 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
343 const GLint winX = 0;
344 const GLint winY = fxMesa->height - 1;
345 const GLushort *data16 = (const GLushort *)((const GLubyte *)info.lfbPtr +
346 (winY - y) * info.strideInBytes +
347 (winX + x) * 2);
348 const GLuint *data32 = (const GLuint *) data16;
349 GLuint i, j;
350 GLuint extraPixel = (n & 1);
351 n -= extraPixel;
352
353 for (i = j = 0; i < n; i += 2, j++) {
354 GLuint pixel = data32[j];
355 rgba[i][0] = FX_rgb_scale_5[(pixel >> 10) & 0x1F];
356 rgba[i][1] = FX_rgb_scale_5[(pixel >> 5) & 0x1F];
357 rgba[i][2] = FX_rgb_scale_5[ pixel & 0x1F];
358 rgba[i][3] = (pixel & 0x8000) ? 255 : 0;
359 rgba[i+1][0] = FX_rgb_scale_5[(pixel >> 26) & 0x1F];
360 rgba[i+1][1] = FX_rgb_scale_5[(pixel >> 21) & 0x1F];
361 rgba[i+1][2] = FX_rgb_scale_5[(pixel >> 16) & 0x1F];
362 rgba[i+1][3] = (pixel & 0x80000000) ? 255 : 0;
363 }
364 if (extraPixel) {
365 GLushort pixel = data16[n];
366 rgba[n][0] = FX_rgb_scale_5[(pixel >> 10) & 0x1F];
367 rgba[n][1] = FX_rgb_scale_5[(pixel >> 5) & 0x1F];
368 rgba[n][2] = FX_rgb_scale_5[ pixel & 0x1F];
369 rgba[n][3] = (pixel & 0x8000) ? 255 : 0;
370 }
371
372 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
373 }
374 }
375
376 /*
377 * Read a span of 16-bit RGB pixels. Note, we don't worry about cliprects
378 * since OpenGL says obscured pixels have undefined values.
379 */
380 static void fxReadRGBASpan_RGB565 (const GLcontext * ctx,
381 GLuint n,
382 GLint x, GLint y,
383 GLubyte rgba[][4])
384 {
385 fxMesaContext fxMesa = FX_CONTEXT(ctx);
386 GrLfbInfo_t info;
387 info.size = sizeof(GrLfbInfo_t);
388 if (grLfbLock(GR_LFB_READ_ONLY, fxMesa->currentFB,
389 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
390 const GLint winX = 0;
391 const GLint winY = fxMesa->height - 1;
392 const GLushort *data16 = (const GLushort *)((const GLubyte *)info.lfbPtr +
393 (winY - y) * info.strideInBytes +
394 (winX + x) * 2);
395 const GLuint *data32 = (const GLuint *) data16;
396 GLuint i, j;
397 GLuint extraPixel = (n & 1);
398 n -= extraPixel;
399
400 for (i = j = 0; i < n; i += 2, j++) {
401 GLuint pixel = data32[j];
402 rgba[i][0] = FX_rgb_scale_5[(pixel >> 11) & 0x1F];
403 rgba[i][1] = FX_rgb_scale_6[(pixel >> 5) & 0x3F];
404 rgba[i][2] = FX_rgb_scale_5[ pixel & 0x1F];
405 rgba[i][3] = 255;
406 rgba[i+1][0] = FX_rgb_scale_5[(pixel >> 27) & 0x1F];
407 rgba[i+1][1] = FX_rgb_scale_6[(pixel >> 21) & 0x3F];
408 rgba[i+1][2] = FX_rgb_scale_5[(pixel >> 16) & 0x1F];
409 rgba[i+1][3] = 255;
410 }
411 if (extraPixel) {
412 GLushort pixel = data16[n];
413 rgba[n][0] = FX_rgb_scale_5[(pixel >> 11) & 0x1F];
414 rgba[n][1] = FX_rgb_scale_6[(pixel >> 5) & 0x3F];
415 rgba[n][2] = FX_rgb_scale_5[ pixel & 0x1F];
416 rgba[n][3] = 255;
417 }
418
419 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
420 }
421 }
422
423 /*
424 * Read a span of 32-bit RGB pixels. Note, we don't worry about cliprects
425 * since OpenGL says obscured pixels have undefined values.
426 */
427 static void fxReadRGBASpan_ARGB8888 (const GLcontext * ctx,
428 GLuint n,
429 GLint x, GLint y,
430 GLubyte rgba[][4])
431 {
432 fxMesaContext fxMesa = FX_CONTEXT(ctx);
433 GLuint i;
434 grLfbReadRegion(fxMesa->currentFB, x, fxMesa->height - 1 - y, n, 1, n * 4, rgba);
435 for (i = 0; i < n; i++) {
436 GLubyte c = rgba[i][0];
437 rgba[i][0] = rgba[i][2];
438 rgba[i][2] = c;
439 }
440 }
441
442
443 /************************************************************************/
444 /***** Depth functions (optimized) *****/
445 /************************************************************************/
446
447 static void
448 fxReadDepthSpan_Z16(GLcontext * ctx,
449 GLuint n, GLint x, GLint y, GLdepth depth[])
450 {
451 fxMesaContext fxMesa = FX_CONTEXT(ctx);
452 GLint bottom = fxMesa->height - 1;
453 GLushort depth16[MAX_WIDTH];
454 GLuint i;
455
456 if (TDFX_DEBUG & VERBOSE_DRIVER) {
457 fprintf(stderr, "fxReadDepthSpan_Z16(...)\n");
458 }
459
460 grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth16);
461 for (i = 0; i < n; i++) {
462 depth[i] = depth16[i];
463 }
464 }
465
466
467 static void
468 fxReadDepthSpan_Z24(GLcontext * ctx,
469 GLuint n, GLint x, GLint y, GLdepth depth[])
470 {
471 fxMesaContext fxMesa = FX_CONTEXT(ctx);
472 GLint bottom = fxMesa->height - 1;
473 GLuint i;
474
475 if (TDFX_DEBUG & VERBOSE_DRIVER) {
476 fprintf(stderr, "fxReadDepthSpan_Z24(...)\n");
477 }
478
479 grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth);
480 for (i = 0; i < n; i++) {
481 depth[i] &= 0xffffff;
482 }
483 }
484
485
486 /************************************************************************/
487 /***** Stencil functions (optimized) *****/
488 /************************************************************************/
489
490 static void
491 fxWriteStencilSpan (GLcontext *ctx, GLuint n, GLint x, GLint y,
492 const GLstencil stencil[], const GLubyte mask[])
493 {
494 /*
495 * XXX todo
496 */
497 }
498
499 static void
500 fxReadStencilSpan(GLcontext * ctx,
501 GLuint n, GLint x, GLint y, GLstencil stencil[])
502 {
503 fxMesaContext fxMesa = FX_CONTEXT(ctx);
504 GLint bottom = fxMesa->height - 1;
505 GLuint zs32[MAX_WIDTH];
506 GLuint i;
507
508 if (TDFX_DEBUG & VERBOSE_DRIVER) {
509 fprintf(stderr, "fxReadStencilSpan(...)\n");
510 }
511
512 grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, zs32);
513 for (i = 0; i < n; i++) {
514 stencil[i] = zs32[i] >> 24;
515 }
516 }
517
518 static void
519 fxWriteStencilPixels (GLcontext *ctx, GLuint n,
520 const GLint x[], const GLint y[],
521 const GLstencil stencil[],
522 const GLubyte mask[])
523 {
524 /*
525 * XXX todo
526 */
527 }
528
529 static void
530 fxReadStencilPixels (GLcontext *ctx, GLuint n,
531 const GLint x[], const GLint y[],
532 GLstencil stencil[])
533 {
534 /*
535 * XXX todo
536 */
537 }
538
539
540
541 /*
542 * This function is called to specify which buffer to read and write
543 * for software rasterization (swrast) fallbacks. This doesn't necessarily
544 * correspond to glDrawBuffer() or glReadBuffer() calls.
545 */
546 static void
547 fxDDSetBuffer(GLcontext * ctx, GLframebuffer * buffer, GLuint bufferBit)
548 {
549 fxMesaContext fxMesa = FX_CONTEXT(ctx);
550 (void) buffer;
551
552 if (TDFX_DEBUG & VERBOSE_DRIVER) {
553 fprintf(stderr, "fxDDSetBuffer(%x)\n", (int)bufferBit);
554 }
555
556 if (bufferBit == DD_FRONT_LEFT_BIT) {
557 fxMesa->currentFB = GR_BUFFER_FRONTBUFFER;
558 grRenderBuffer(fxMesa->currentFB);
559 }
560 else if (bufferBit == DD_BACK_LEFT_BIT) {
561 fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
562 grRenderBuffer(fxMesa->currentFB);
563 }
564 }
565
566
567 /************************************************************************/
568
569
570
571 void
572 fxSetupDDSpanPointers(GLcontext * ctx)
573 {
574 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
575 fxMesaContext fxMesa = FX_CONTEXT(ctx);
576
577 swdd->SetBuffer = fxDDSetBuffer;
578
579 switch (fxMesa->colDepth) {
580 case 15:
581 swdd->WriteRGBASpan = tdfxWriteRGBASpan_ARGB1555;
582 swdd->WriteRGBSpan = tdfxWriteRGBSpan_ARGB1555;
583 swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_ARGB1555;
584 swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_ARGB1555;
585 swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_ARGB1555;
586 swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_ARGB1555;
587 swdd->ReadRGBAPixels = tdfxReadRGBAPixels_ARGB1555;
588
589 swdd->WriteDepthSpan = tdfxWriteDepthSpan_Z16;
590 swdd->WriteDepthPixels = tdfxWriteDepthPixels_Z16;
591 swdd->ReadDepthSpan = /*td*/fxReadDepthSpan_Z16;
592 swdd->ReadDepthPixels = tdfxReadDepthPixels_Z16;
593 break;
594 case 16:
595 swdd->WriteRGBASpan = tdfxWriteRGBASpan_RGB565;
596 swdd->WriteRGBSpan = tdfxWriteRGBSpan_RGB565;
597 swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_RGB565;
598 swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_RGB565;
599 swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_RGB565;
600 swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_RGB565;
601 swdd->ReadRGBAPixels = tdfxReadRGBAPixels_RGB565;
602
603 swdd->WriteDepthSpan = tdfxWriteDepthSpan_Z16;
604 swdd->WriteDepthPixels = tdfxWriteDepthPixels_Z16;
605 swdd->ReadDepthSpan = /*td*/fxReadDepthSpan_Z16;
606 swdd->ReadDepthPixels = tdfxReadDepthPixels_Z16;
607 break;
608 case 32:
609 swdd->WriteRGBASpan = tdfxWriteRGBASpan_ARGB8888;
610 swdd->WriteRGBSpan = tdfxWriteRGBSpan_ARGB8888;
611 swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_ARGB8888;
612 swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_ARGB8888;
613 swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_ARGB8888;
614 swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_ARGB8888;
615 swdd->ReadRGBAPixels = tdfxReadRGBAPixels_ARGB8888;
616
617 swdd->WriteDepthSpan = tdfxWriteDepthSpan_Z24;
618 swdd->WriteDepthPixels = tdfxWriteDepthPixels_Z24;
619 swdd->ReadDepthSpan = /*td*/fxReadDepthSpan_Z24;
620 swdd->ReadDepthPixels = tdfxReadDepthPixels_Z24;
621 break;
622 }
623
624 if (fxMesa->haveHwStencil) {
625 swdd->WriteStencilSpan = fxWriteStencilSpan;
626 swdd->ReadStencilSpan = fxReadStencilSpan;
627 swdd->WriteStencilPixels = fxWriteStencilPixels;
628 swdd->ReadStencilPixels = fxReadStencilPixels;
629 }
630 #if 0
631 swdd->WriteCI8Span = NULL;
632 swdd->WriteCI32Span = NULL;
633 swdd->WriteMonoCISpan = NULL;
634 swdd->WriteCI32Pixels = NULL;
635 swdd->WriteMonoCIPixels = NULL;
636 swdd->ReadCI32Span = NULL;
637 swdd->ReadCI32Pixels = NULL;
638
639 swdd->SpanRenderStart = tdfxSpanRenderStart; /* BEGIN_BOARD_LOCK */
640 swdd->SpanRenderFinish = tdfxSpanRenderFinish; /* END_BOARD_LOCK */
641 #endif
642 }
643
644
645 #else
646
647
648 /*
649 * Need this to provide at least one external definition.
650 */
651
652 extern int gl_fx_dummy_function_span(void);
653 int
654 gl_fx_dummy_function_span(void)
655 {
656 return 0;
657 }
658
659 #endif /* FX */