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