updates from Daniel Borca
[mesa.git] / src / mesa / drivers / glide / fxddspan.c
1 /* Hack alert:
2 * The performance hit is disastruous for SPAN functions.
3 * Should we use SpanRenderStart / SpanRenderFinish in `swrast.h'
4 * for locking / unlocking the LFB?
5 * Optimize and check endianess for `read_R8G8B8_pixels'
6 */
7
8 /* $Id: fxddspan.c,v 1.25 2003/10/02 17:36:44 brianp Exp $ */
9
10 /*
11 * Mesa 3-D graphics library
12 * Version: 4.0
13 *
14 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice shall be included
24 * in all copies or substantial portions of the Software.
25 *
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
29 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
30 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 */
33
34 /* Authors:
35 * David Bucciarelli
36 * Brian Paul
37 * Daryll Strauss
38 * Keith Whitwell
39 * Daniel Borca
40 * Hiroshi Morii
41 */
42
43
44 /* fxdd.c - 3Dfx VooDoo Mesa span and pixel functions */
45
46
47 #ifdef HAVE_CONFIG_H
48 #include "conf.h"
49 #endif
50
51 #if defined(FX)
52
53 #include "fxdrv.h"
54 #include "fxglidew.h"
55 #include "swrast/swrast.h"
56
57 #ifdef _MSC_VER
58 #ifdef _WIN32
59 #pragma warning( disable : 4090 4022 )
60 /* 4101 : "different 'const' qualifier"
61 * 4022 : "pointer mistmatch for actual parameter 'n'
62 */
63 #endif
64 #endif
65
66
67
68 #define writeRegionClipped(fxm,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \
69 FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)
70
71
72
73 /* KW: Rearranged the args in the call to grLfbWriteRegion().
74 */
75 #define LFB_WRITE_SPAN_MESA(dst_buffer, \
76 dst_x, \
77 dst_y, \
78 src_width, \
79 src_stride, \
80 src_data) \
81 writeRegionClipped(fxMesa, dst_buffer, \
82 dst_x, \
83 dst_y, \
84 GR_LFB_SRC_FMT_8888, \
85 src_width, \
86 1, \
87 src_stride, \
88 src_data) \
89
90
91 /************************************************************************/
92 /***** Span functions *****/
93 /************************************************************************/
94
95
96 static void
97 fxDDWriteRGBASpan(const GLcontext * ctx,
98 GLuint n, GLint x, GLint y,
99 const GLubyte rgba[][4], const GLubyte mask[])
100 {
101 fxMesaContext fxMesa = FX_CONTEXT(ctx);
102 GLuint i;
103 GLint bottom = fxMesa->height - 1;
104
105 if (TDFX_DEBUG & VERBOSE_DRIVER) {
106 fprintf(stderr, "%s(...)\n", __FUNCTION__);
107 }
108
109 if (mask) {
110 int span = 0;
111
112 for (i = 0; i < n; i++) {
113 if (mask[i]) {
114 ++span;
115 }
116 else {
117 if (span > 0) {
118 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + i - span,
119 bottom - y,
120 /* GR_LFB_SRC_FMT_8888, */ span, /*1, */ 0,
121 (void *) rgba[i - span]);
122 span = 0;
123 }
124 }
125 }
126
127 if (span > 0)
128 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + n - span, bottom - y,
129 /* GR_LFB_SRC_FMT_8888, */ span, /*1, */ 0,
130 (void *) rgba[n - span]);
131 }
132 else
133 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x, bottom - y, /* GR_LFB_SRC_FMT_8888, */
134 n, /* 1, */ 0, (void *) rgba);
135 }
136
137
138 static void
139 fxDDWriteRGBSpan(const GLcontext * ctx,
140 GLuint n, GLint x, GLint y,
141 const GLubyte rgb[][3], const GLubyte mask[])
142 {
143 fxMesaContext fxMesa = FX_CONTEXT(ctx);
144 GLuint i;
145 GLint bottom = fxMesa->height - 1;
146 GLubyte rgba[MAX_WIDTH][4];
147
148 if (TDFX_DEBUG & VERBOSE_DRIVER) {
149 fprintf(stderr, "%s(...)\n", __FUNCTION__);
150 }
151
152 if (mask) {
153 int span = 0;
154
155 for (i = 0; i < n; i++) {
156 if (mask[i]) {
157 rgba[span][RCOMP] = rgb[i][0];
158 rgba[span][GCOMP] = rgb[i][1];
159 rgba[span][BCOMP] = rgb[i][2];
160 rgba[span][ACOMP] = 255;
161 ++span;
162 }
163 else {
164 if (span > 0) {
165 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + i - span,
166 bottom - y,
167 /*GR_LFB_SRC_FMT_8888, */ span, /* 1, */ 0,
168 (void *) rgba);
169 span = 0;
170 }
171 }
172 }
173
174 if (span > 0)
175 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + n - span, bottom - y,
176 /*GR_LFB_SRC_FMT_8888, */ span, /* 1, */ 0,
177 (void *) rgba);
178 }
179 else {
180 for (i = 0; i < n; i++) {
181 rgba[i][RCOMP] = rgb[i][0];
182 rgba[i][GCOMP] = rgb[i][1];
183 rgba[i][BCOMP] = rgb[i][2];
184 rgba[i][ACOMP] = 255;
185 }
186
187 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x, bottom - y, /* GR_LFB_SRC_FMT_8888, */
188 n, /* 1, */ 0, (void *) rgba);
189 }
190 }
191
192
193 static void
194 fxDDWriteMonoRGBASpan(const GLcontext * ctx,
195 GLuint n, GLint x, GLint y,
196 const GLchan color[4], const GLubyte mask[])
197 {
198 fxMesaContext fxMesa = FX_CONTEXT(ctx);
199 GLuint i;
200 GLint bottom = fxMesa->height - 1;
201 GLuint data[MAX_WIDTH];
202 GrColor_t gColor = FXCOLOR4(color);
203
204 if (TDFX_DEBUG & VERBOSE_DRIVER) {
205 fprintf(stderr, "%s(...)\n", __FUNCTION__);
206 }
207
208 if (mask) {
209 int span = 0;
210
211 for (i = 0; i < n; i++) {
212 if (mask[i]) {
213 data[span] = (GLuint) gColor;
214 ++span;
215 }
216 else {
217 if (span > 0) {
218 writeRegionClipped(fxMesa, fxMesa->currentFB, x + i - span,
219 bottom - y, GR_LFB_SRC_FMT_8888, span, 1, 0,
220 (void *) data);
221 span = 0;
222 }
223 }
224 }
225
226 if (span > 0)
227 writeRegionClipped(fxMesa, fxMesa->currentFB, x + n - span,
228 bottom - y, GR_LFB_SRC_FMT_8888, span, 1, 0,
229 (void *) data);
230 }
231 else {
232 for (i = 0; i < n; i++) {
233 data[i] = (GLuint) gColor;
234 }
235
236 writeRegionClipped(fxMesa, fxMesa->currentFB, x, bottom - y,
237 GR_LFB_SRC_FMT_8888, n, 1, 0, (void *) data);
238 }
239 }
240
241
242 #if 0
243 static void
244 fxDDReadRGBASpan(const GLcontext * ctx,
245 GLuint n, GLint x, GLint y, GLubyte rgba[][4])
246 {
247 fxMesaContext fxMesa = FX_CONTEXT(ctx);
248 GLushort data[MAX_WIDTH];
249 GLuint i;
250 GLint bottom = fxMesa->height - 1;
251
252 if (TDFX_DEBUG & VERBOSE_DRIVER) {
253 fprintf(stderr, "%s(...)\n", __FUNCTION__);
254 }
255
256 assert(n < MAX_WIDTH);
257
258 FX_grLfbReadRegion(fxMesa->currentFB, x, bottom - y, n, 1, 0, data);
259
260 for (i = 0; i < n; i++) {
261 GLushort pixel = data[i];
262 rgba[i][RCOMP] = FX_PixelToR[pixel];
263 rgba[i][GCOMP] = FX_PixelToG[pixel];
264 rgba[i][BCOMP] = FX_PixelToB[pixel];
265 rgba[i][ACOMP] = 255;
266 }
267 }
268 #endif
269
270
271 /*
272 * Read a span of 16-bit RGB pixels. Note, we don't worry about cliprects
273 * since OpenGL says obscured pixels have undefined values.
274 */
275 static void
276 read_R5G6B5_span(const GLcontext * ctx,
277 GLuint n, GLint x, GLint y, GLubyte rgba[][4])
278 {
279 fxMesaContext fxMesa = FX_CONTEXT(ctx);
280 GrLfbInfo_t info;
281 BEGIN_BOARD_LOCK();
282 if (grLfbLock(GR_LFB_READ_ONLY,
283 fxMesa->currentFB,
284 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
285 const GLint winX = 0;
286 const GLint winY = fxMesa->height - 1;
287 const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
288 const GLushort *data16 = (const GLushort *) info.lfbPtr
289 + (winY - y) * srcStride + (winX + x);
290 const GLuint *data32 = (const GLuint *) data16;
291 GLuint i, j;
292 GLuint extraPixel = (n & 1);
293 n -= extraPixel;
294 for (i = j = 0; i < n; i += 2, j++) {
295 GLuint pixel = data32[j];
296 GLuint pixel0 = pixel & 0xffff;
297 GLuint pixel1 = pixel >> 16;
298 rgba[i][RCOMP] = FX_PixelToR[pixel0];
299 rgba[i][GCOMP] = FX_PixelToG[pixel0];
300 rgba[i][BCOMP] = FX_PixelToB[pixel0];
301 rgba[i][ACOMP] = 255;
302 rgba[i + 1][RCOMP] = FX_PixelToR[pixel1];
303 rgba[i + 1][GCOMP] = FX_PixelToG[pixel1];
304 rgba[i + 1][BCOMP] = FX_PixelToB[pixel1];
305 rgba[i + 1][ACOMP] = 255;
306 }
307 if (extraPixel) {
308 GLushort pixel = data16[n];
309 rgba[n][RCOMP] = FX_PixelToR[pixel];
310 rgba[n][GCOMP] = FX_PixelToG[pixel];
311 rgba[n][BCOMP] = FX_PixelToB[pixel];
312 rgba[n][ACOMP] = 255;
313 }
314
315 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
316 }
317 END_BOARD_LOCK();
318 }
319
320 /*
321 * Read a span of 15-bit RGB pixels. Note, we don't worry about cliprects
322 * since OpenGL says obscured pixels have undefined values.
323 */
324 static void read_R5G5B5_span (const GLcontext * ctx,
325 GLuint n,
326 GLint x, GLint y,
327 GLubyte rgba[][4])
328 {
329 fxMesaContext fxMesa = FX_CONTEXT(ctx);
330 GrLfbInfo_t info;
331 BEGIN_BOARD_LOCK();
332 if (grLfbLock(GR_LFB_READ_ONLY,
333 fxMesa->currentFB,
334 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
335 const GLint winX = 0;
336 const GLint winY = fxMesa->height - 1;
337 const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
338 const GLushort *data16 = (const GLushort *) info.lfbPtr
339 + (winY - y) * srcStride + (winX + x);
340 const GLuint *data32 = (const GLuint *) data16;
341 GLuint i, j;
342 GLuint extraPixel = (n & 1);
343 n -= extraPixel;
344 for (i = j = 0; i < n; i += 2, j++) {
345 GLuint pixel = data32[j];
346 rgba[i][RCOMP] = FX_rgb_scale_5[ pixel & 0x1f];
347 rgba[i][GCOMP] = FX_rgb_scale_5[(pixel >> 5) & 0x1f];
348 rgba[i][BCOMP] = FX_rgb_scale_5[(pixel >> 10) & 0x1f];
349 rgba[i][ACOMP] = (pixel & 0x8000) ? 255 : 0;
350 rgba[i + 1][RCOMP] = FX_rgb_scale_5[(pixel >> 16) & 0x1f];
351 rgba[i + 1][GCOMP] = FX_rgb_scale_5[(pixel >> 21) & 0x1f];
352 rgba[i + 1][BCOMP] = FX_rgb_scale_5[(pixel >> 26) & 0x1f];
353 rgba[i + 1][ACOMP] = (pixel & 0x80000000) ? 255 : 0;
354 }
355 if (extraPixel) {
356 GLushort pixel = data16[n];
357 rgba[n][RCOMP] = FX_rgb_scale_5[ pixel & 0x1f];
358 rgba[n][GCOMP] = FX_rgb_scale_5[(pixel >> 5) & 0x1f];
359 rgba[n][BCOMP] = FX_rgb_scale_5[(pixel >> 10) & 0x1f];
360 rgba[n][ACOMP] = (pixel & 0x8000) ? 255 : 0;
361 }
362
363 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
364 }
365 END_BOARD_LOCK();
366 }
367
368 /*
369 * Read a span of 32-bit RGB pixels. Note, we don't worry about cliprects
370 * since OpenGL says obscured pixels have undefined values.
371 */
372 static void read_R8G8B8_span (const GLcontext * ctx,
373 GLuint n,
374 GLint x, GLint y,
375 GLubyte rgba[][4])
376 {
377 fxMesaContext fxMesa = FX_CONTEXT(ctx);
378 BEGIN_BOARD_LOCK();
379 grLfbReadRegion(fxMesa->currentFB, x, fxMesa->height - 1 - y, n, 1, n * 4, rgba);
380 END_BOARD_LOCK();
381 }
382
383
384 /************************************************************************/
385 /***** Pixel functions *****/
386 /************************************************************************/
387
388 static void
389 fxDDWriteRGBAPixels(const GLcontext * ctx,
390 GLuint n, const GLint x[], const GLint y[],
391 CONST GLubyte rgba[][4], const GLubyte mask[])
392 {
393 fxMesaContext fxMesa = FX_CONTEXT(ctx);
394 GLuint i;
395 GLint bottom = fxMesa->height - 1;
396
397 if (TDFX_DEBUG & VERBOSE_DRIVER) {
398 fprintf(stderr, "%s(...)\n", __FUNCTION__);
399 }
400
401 for (i = 0; i < n; i++)
402 if (mask[i])
403 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x[i], bottom - y[i],
404 1, 1, (void *) rgba[i]);
405 }
406
407 static void
408 fxDDWriteMonoRGBAPixels(const GLcontext * ctx,
409 GLuint n, const GLint x[], const GLint y[],
410 const GLchan color[4], const GLubyte mask[])
411 {
412 fxMesaContext fxMesa = FX_CONTEXT(ctx);
413 GLuint i;
414 GLint bottom = fxMesa->height - 1;
415 GrColor_t gColor = FXCOLOR4(color);
416
417 if (TDFX_DEBUG & VERBOSE_DRIVER) {
418 fprintf(stderr, "%s(...)\n", __FUNCTION__);
419 }
420
421 for (i = 0; i < n; i++)
422 if (mask[i])
423 writeRegionClipped(fxMesa, fxMesa->currentFB, x[i], bottom - y[i],
424 GR_LFB_SRC_FMT_8888, 1, 1, 0, (void *) &gColor);
425 }
426
427
428 static void
429 read_R5G6B5_pixels(const GLcontext * ctx,
430 GLuint n, const GLint x[], const GLint y[],
431 GLubyte rgba[][4], const GLubyte mask[])
432 {
433 fxMesaContext fxMesa = FX_CONTEXT(ctx);
434 GrLfbInfo_t info;
435 BEGIN_BOARD_LOCK();
436 if (grLfbLock(GR_LFB_READ_ONLY,
437 fxMesa->currentFB,
438 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
439 const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
440 const GLint winX = 0;
441 const GLint winY = fxMesa->height - 1;
442 GLuint i;
443 for (i = 0; i < n; i++) {
444 if (mask[i]) {
445 const GLushort *data16 = (const GLushort *) info.lfbPtr
446 + (winY - y[i]) * srcStride + (winX + x[i]);
447 const GLushort pixel = *data16;
448 rgba[i][RCOMP] = FX_PixelToR[pixel];
449 rgba[i][GCOMP] = FX_PixelToG[pixel];
450 rgba[i][BCOMP] = FX_PixelToB[pixel];
451 rgba[i][ACOMP] = 255;
452 }
453 }
454 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
455 }
456 END_BOARD_LOCK();
457 }
458
459
460 static void read_R5G5B5_pixels (const GLcontext * ctx,
461 GLuint n,
462 const GLint x[], const GLint y[],
463 GLubyte rgba[][4],
464 const GLubyte mask[])
465 {
466 fxMesaContext fxMesa = FX_CONTEXT(ctx);
467 GrLfbInfo_t info;
468 BEGIN_BOARD_LOCK();
469 if (grLfbLock(GR_LFB_READ_ONLY,
470 fxMesa->currentFB,
471 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
472 const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
473 const GLint winX = 0;
474 const GLint winY = fxMesa->height - 1;
475 GLuint i;
476 for (i = 0; i < n; i++) {
477 if (mask[i]) {
478 const GLushort *data16 = (const GLushort *) info.lfbPtr
479 + (winY - y[i]) * srcStride + (winX + x[i]);
480 const GLushort pixel = *data16;
481 rgba[i][RCOMP] = FX_rgb_scale_5[ pixel & 0x1f];
482 rgba[i][GCOMP] = FX_rgb_scale_5[(pixel >> 5) & 0x1f];
483 rgba[i][BCOMP] = FX_rgb_scale_5[(pixel >> 10) & 0x1f];
484 rgba[i][ACOMP] = (pixel & 0x8000) ? 255 : 0;
485 }
486 }
487 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
488 }
489 END_BOARD_LOCK();
490 }
491
492
493 static void
494 read_R8G8B8_pixels(const GLcontext * ctx,
495 GLuint n, const GLint x[], const GLint y[],
496 GLubyte rgba[][4], const GLubyte mask[])
497 {
498 fxMesaContext fxMesa = FX_CONTEXT(ctx);
499 GrLfbInfo_t info;
500 BEGIN_BOARD_LOCK();
501 if (grLfbLock(GR_LFB_READ_ONLY,
502 fxMesa->currentFB,
503 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
504 const GLint srcStride = info.strideInBytes / 4; /* stride in GLuints */
505 const GLint winX = 0;
506 const GLint winY = fxMesa->height - 1;
507 GLuint i;
508 for (i = 0; i < n; i++) {
509 if (mask[i]) {
510 const GLuint *data32 = (const GLuint *) info.lfbPtr
511 + (winY - y[i]) * srcStride + (winX + x[i]);
512 const GLuint pixel = *data32;
513 *(GLuint *)&rgba[i][0] = pixel;
514 }
515 }
516 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
517 }
518 END_BOARD_LOCK();
519 }
520
521
522
523 /************************************************************************/
524 /***** Depth functions *****/
525 /************************************************************************/
526
527 void
528 fxDDWriteDepthSpan(GLcontext * ctx,
529 GLuint n, GLint x, GLint y, const GLdepth depth[],
530 const GLubyte mask[])
531 {
532 fxMesaContext fxMesa = FX_CONTEXT(ctx);
533 GLint bottom = fxMesa->height - 1;
534
535 if (TDFX_DEBUG & VERBOSE_DRIVER) {
536 fprintf(stderr, "%s(...)\n", __FUNCTION__);
537 }
538
539
540 if (mask) {
541 GLint i;
542 for (i = 0; i < n; i++) {
543 if (mask[i]) {
544 GLshort d = depth[i];
545 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y,
546 GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d);
547 }
548 }
549 }
550 else {
551 GLushort depth16[MAX_WIDTH];
552 GLint i;
553 for (i = 0; i < n; i++) {
554 depth16[i] = depth[i];
555 }
556 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom - y,
557 GR_LFB_SRC_FMT_ZA16, n, 1, 0, (void *) depth16);
558 }
559 }
560
561
562 void
563 fxDDWriteDepth32Span(GLcontext * ctx,
564 GLuint n, GLint x, GLint y, const GLdepth depth[],
565 const GLubyte mask[])
566 {
567 fxMesaContext fxMesa = FX_CONTEXT(ctx);
568 GLint bottom = fxMesa->height - 1;
569 GLint i;
570
571 if (TDFX_DEBUG & VERBOSE_DRIVER) {
572 fprintf(stderr, "%s(...)\n", __FUNCTION__);
573 }
574
575
576 if (mask) {
577 for (i = 0; i < n; i++) {
578 if (mask[i]) {
579 GLuint d = depth[i] << 8;
580 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y,
581 GR_LFBWRITEMODE_Z32, 1, 1, 0, (void *) &d);
582 }
583 }
584 }
585 else {
586 GLuint depth32[MAX_WIDTH];
587 for (i = 0; i < n; i++) {
588 depth32[i] = depth[i] << 8;
589 }
590 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom - y,
591 GR_LFBWRITEMODE_Z32, n, 1, 0, (void *) depth32);
592 }
593 }
594
595
596 void
597 fxDDReadDepthSpan(GLcontext * ctx,
598 GLuint n, GLint x, GLint y, GLdepth depth[])
599 {
600 fxMesaContext fxMesa = FX_CONTEXT(ctx);
601 GLint bottom = fxMesa->height - 1;
602 GLushort depth16[MAX_WIDTH];
603 GLuint i;
604
605 if (TDFX_DEBUG & VERBOSE_DRIVER) {
606 fprintf(stderr, "%s(...)\n", __FUNCTION__);
607 }
608
609 grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth16);
610 for (i = 0; i < n; i++) {
611 depth[i] = depth16[i];
612 }
613 }
614
615
616 void
617 fxDDReadDepth32Span(GLcontext * ctx,
618 GLuint n, GLint x, GLint y, GLdepth depth[])
619 {
620 fxMesaContext fxMesa = FX_CONTEXT(ctx);
621 GLint bottom = fxMesa->height - 1;
622
623 if (TDFX_DEBUG & VERBOSE_DRIVER) {
624 fprintf(stderr, "%s(...)\n", __FUNCTION__);
625 }
626
627 grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth);
628 }
629
630
631
632 void
633 fxDDWriteDepthPixels(GLcontext * ctx,
634 GLuint n, const GLint x[], const GLint y[],
635 const GLdepth depth[], const GLubyte mask[])
636 {
637 fxMesaContext fxMesa = FX_CONTEXT(ctx);
638 GLint bottom = fxMesa->height - 1;
639 GLuint i;
640
641 if (TDFX_DEBUG & VERBOSE_DRIVER) {
642 fprintf(stderr, "%s(...)\n", __FUNCTION__);
643 }
644
645 for (i = 0; i < n; i++) {
646 if (mask[i]) {
647 int xpos = x[i];
648 int ypos = bottom - y[i];
649 GLushort d = depth[i];
650 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos,
651 GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d);
652 }
653 }
654 }
655
656
657 void
658 fxDDWriteDepth32Pixels(GLcontext * ctx,
659 GLuint n, const GLint x[], const GLint y[],
660 const GLdepth depth[], const GLubyte mask[])
661 {
662 fxMesaContext fxMesa = FX_CONTEXT(ctx);
663 GLint bottom = fxMesa->height - 1;
664 GLuint i;
665
666 if (TDFX_DEBUG & VERBOSE_DRIVER) {
667 fprintf(stderr, "%s(...)\n", __FUNCTION__);
668 }
669
670 for (i = 0; i < n; i++) {
671 if (mask[i]) {
672 int xpos = x[i];
673 int ypos = bottom - y[i];
674 GLuint d = depth[i] << 8;
675 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos,
676 GR_LFBWRITEMODE_Z32, 1, 1, 0, (void *) &d);
677 }
678 }
679 }
680
681
682 void
683 fxDDReadDepthPixels(GLcontext * ctx, GLuint n,
684 const GLint x[], const GLint y[], GLdepth depth[])
685 {
686 fxMesaContext fxMesa = FX_CONTEXT(ctx);
687 GLint bottom = fxMesa->height - 1;
688 GLuint i;
689
690 if (TDFX_DEBUG & VERBOSE_DRIVER) {
691 fprintf(stderr, "%s(...)\n", __FUNCTION__);
692 }
693
694 for (i = 0; i < n; i++) {
695 int xpos = x[i];
696 int ypos = bottom - y[i];
697 GLushort d;
698 grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &d);
699 depth[i] = d;
700 }
701 }
702
703
704 void
705 fxDDReadDepth32Pixels(GLcontext * ctx, GLuint n,
706 const GLint x[], const GLint y[], GLdepth depth[])
707 {
708 fxMesaContext fxMesa = FX_CONTEXT(ctx);
709 GLint bottom = fxMesa->height - 1;
710 GLuint i;
711
712 if (TDFX_DEBUG & VERBOSE_DRIVER) {
713 fprintf(stderr, "%s(...)\n", __FUNCTION__);
714 }
715
716 for (i = 0; i < n; i++) {
717 int xpos = x[i];
718 int ypos = bottom - y[i];
719 grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &depth[i]);
720 }
721 }
722
723
724
725 /* Set the buffer used for reading */
726 /* XXX support for separate read/draw buffers hasn't been tested */
727 static void
728 fxDDSetBuffer(GLcontext * ctx, GLframebuffer * buffer, GLuint bufferBit)
729 {
730 fxMesaContext fxMesa = FX_CONTEXT(ctx);
731 (void) buffer;
732
733 if (TDFX_DEBUG & VERBOSE_DRIVER) {
734 fprintf(stderr, "%s(%x)\n", __FUNCTION__, (int)bufferBit);
735 }
736
737 if (bufferBit == FRONT_LEFT_BIT) {
738 fxMesa->currentFB = GR_BUFFER_FRONTBUFFER;
739 grRenderBuffer(fxMesa->currentFB);
740 }
741 else if (bufferBit == BACK_LEFT_BIT) {
742 fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
743 grRenderBuffer(fxMesa->currentFB);
744 }
745 }
746
747
748 /************************************************************************/
749
750
751
752 void
753 fxSetupDDSpanPointers(GLcontext * ctx)
754 {
755 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
756
757 swdd->SetBuffer = fxDDSetBuffer;
758
759 swdd->WriteRGBASpan = fxDDWriteRGBASpan;
760 swdd->WriteRGBSpan = fxDDWriteRGBSpan;
761 swdd->WriteMonoRGBASpan = fxDDWriteMonoRGBASpan;
762 swdd->WriteRGBAPixels = fxDDWriteRGBAPixels;
763 swdd->WriteMonoRGBAPixels = fxDDWriteMonoRGBAPixels;
764
765 /* swdd->ReadRGBASpan =fxDDReadRGBASpan; */
766 {
767 fxMesaContext fxMesa = FX_CONTEXT(ctx);
768 switch (fxMesa->colDepth) {
769 case 15:
770 swdd->ReadRGBASpan = read_R5G5B5_span;
771 swdd->ReadRGBAPixels = read_R5G5B5_pixels;
772 swdd->WriteDepthSpan = fxDDWriteDepthSpan;
773 swdd->WriteDepthPixels = fxDDWriteDepthPixels;
774 swdd->ReadDepthSpan = fxDDReadDepthSpan;
775 swdd->ReadDepthPixels = fxDDReadDepthPixels;
776 break;
777 case 16:
778 swdd->ReadRGBASpan = read_R5G6B5_span;
779 swdd->ReadRGBAPixels = read_R5G6B5_pixels;
780 swdd->WriteDepthSpan = fxDDWriteDepthSpan;
781 swdd->WriteDepthPixels = fxDDWriteDepthPixels;
782 swdd->ReadDepthSpan = fxDDReadDepthSpan;
783 swdd->ReadDepthPixels = fxDDReadDepthPixels;
784 break;
785 case 32:
786 swdd->ReadRGBASpan = read_R8G8B8_span;
787 swdd->ReadRGBAPixels = read_R8G8B8_pixels;
788 swdd->WriteDepthSpan = fxDDWriteDepth32Span;
789 swdd->WriteDepthPixels = fxDDWriteDepth32Pixels;
790 swdd->ReadDepthSpan = fxDDReadDepth32Span;
791 swdd->ReadDepthPixels = fxDDReadDepth32Pixels;
792 break;
793 }
794 }
795 }
796
797
798 #else
799
800
801 /*
802 * Need this to provide at least one external definition.
803 */
804
805 extern int gl_fx_dummy_function_span(void);
806 int
807 gl_fx_dummy_function_span(void)
808 {
809 return 0;
810 }
811
812 #endif /* FX */