6e847acce4ecf510e76cbc8486eb6cfddc0c56a7
[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.24 2003/08/19 15:52:53 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 = (fxMesaContext) ctx->DriverCtx;
102 GLuint i;
103 GLint bottom = fxMesa->height - 1;
104
105 if (MESA_VERBOSE & VERBOSE_DRIVER) {
106 fprintf(stderr, "fxmesa: fxDDWriteRGBASpan(...)\n");
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 = (fxMesaContext) ctx->DriverCtx;
144 GLuint i;
145 GLint bottom = fxMesa->height - 1;
146 GLubyte rgba[MAX_WIDTH][4];
147
148 if (MESA_VERBOSE & VERBOSE_DRIVER) {
149 fprintf(stderr, "fxmesa: fxDDWriteRGBSpan()\n");
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 = (fxMesaContext) ctx->DriverCtx;
199 GLuint i;
200 GLint bottom = fxMesa->height - 1;
201 GLuint data[MAX_WIDTH];
202 GrColor_t gColor = FXCOLOR4(color);
203
204 if (MESA_VERBOSE & VERBOSE_DRIVER) {
205 fprintf(stderr, "fxmesa: fxDDWriteMonoRGBASpan(...)\n");
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 = (fxMesaContext) ctx->DriverCtx;
248 GLushort data[MAX_WIDTH];
249 GLuint i;
250 GLint bottom = fxMesa->height - 1;
251
252 printf("read span %d, %d, %d\n", x, y, n);
253 if (MESA_VERBOSE & VERBOSE_DRIVER) {
254 fprintf(stderr, "fxmesa: fxDDReadRGBASpan(...)\n");
255 }
256
257 assert(n < MAX_WIDTH);
258
259 FX_grLfbReadRegion(fxMesa->currentFB, x, bottom - y, n, 1, 0, data);
260
261 for (i = 0; i < n; i++) {
262 GLushort pixel = data[i];
263 rgba[i][RCOMP] = FX_PixelToR[pixel];
264 rgba[i][GCOMP] = FX_PixelToG[pixel];
265 rgba[i][BCOMP] = FX_PixelToB[pixel];
266 rgba[i][ACOMP] = 255;
267 }
268 }
269 #endif
270
271
272 /*
273 * Read a span of 16-bit RGB pixels. Note, we don't worry about cliprects
274 * since OpenGL says obscured pixels have undefined values.
275 */
276 static void
277 read_R5G6B5_span(const GLcontext * ctx,
278 GLuint n, GLint x, GLint y, GLubyte rgba[][4])
279 {
280 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
281 GrLfbInfo_t info;
282 BEGIN_BOARD_LOCK();
283 if (grLfbLock(GR_LFB_READ_ONLY,
284 fxMesa->currentFB,
285 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
286 const GLint winX = 0;
287 const GLint winY = fxMesa->height - 1;
288 const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
289 const GLushort *data16 = (const GLushort *) info.lfbPtr
290 + (winY - y) * srcStride + (winX + x);
291 const GLuint *data32 = (const GLuint *) data16;
292 GLuint i, j;
293 GLuint extraPixel = (n & 1);
294 n -= extraPixel;
295 for (i = j = 0; i < n; i += 2, j++) {
296 GLuint pixel = data32[j];
297 GLuint pixel0 = pixel & 0xffff;
298 GLuint pixel1 = pixel >> 16;
299 rgba[i][RCOMP] = FX_PixelToR[pixel0];
300 rgba[i][GCOMP] = FX_PixelToG[pixel0];
301 rgba[i][BCOMP] = FX_PixelToB[pixel0];
302 rgba[i][ACOMP] = 255;
303 rgba[i + 1][RCOMP] = FX_PixelToR[pixel1];
304 rgba[i + 1][GCOMP] = FX_PixelToG[pixel1];
305 rgba[i + 1][BCOMP] = FX_PixelToB[pixel1];
306 rgba[i + 1][ACOMP] = 255;
307 }
308 if (extraPixel) {
309 GLushort pixel = data16[n];
310 rgba[n][RCOMP] = FX_PixelToR[pixel];
311 rgba[n][GCOMP] = FX_PixelToG[pixel];
312 rgba[n][BCOMP] = FX_PixelToB[pixel];
313 rgba[n][ACOMP] = 255;
314 }
315
316 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
317 }
318 END_BOARD_LOCK();
319 }
320
321 /*
322 * Read a span of 15-bit RGB pixels. Note, we don't worry about cliprects
323 * since OpenGL says obscured pixels have undefined values.
324 */
325 static void read_R5G5B5_span (const GLcontext * ctx,
326 GLuint n,
327 GLint x, GLint y,
328 GLubyte rgba[][4])
329 {
330 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
331 GrLfbInfo_t info;
332 BEGIN_BOARD_LOCK();
333 if (grLfbLock(GR_LFB_READ_ONLY,
334 fxMesa->currentFB,
335 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
336 const GLint winX = 0;
337 const GLint winY = fxMesa->height - 1;
338 const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
339 const GLushort *data16 = (const GLushort *) info.lfbPtr
340 + (winY - y) * srcStride + (winX + x);
341 const GLuint *data32 = (const GLuint *) data16;
342 GLuint i, j;
343 GLuint extraPixel = (n & 1);
344 n -= extraPixel;
345 for (i = j = 0; i < n; i += 2, j++) {
346 GLuint pixel = data32[j];
347 rgba[i][RCOMP] = FX_rgb_scale_5[ pixel & 0x1f];
348 rgba[i][GCOMP] = FX_rgb_scale_5[(pixel >> 5) & 0x1f];
349 rgba[i][BCOMP] = FX_rgb_scale_5[(pixel >> 10) & 0x1f];
350 rgba[i][ACOMP] = (pixel & 0x8000) ? 255 : 0;
351 rgba[i + 1][RCOMP] = FX_rgb_scale_5[(pixel >> 16) & 0x1f];
352 rgba[i + 1][GCOMP] = FX_rgb_scale_5[(pixel >> 21) & 0x1f];
353 rgba[i + 1][BCOMP] = FX_rgb_scale_5[(pixel >> 26) & 0x1f];
354 rgba[i + 1][ACOMP] = (pixel & 0x80000000) ? 255 : 0;
355 }
356 if (extraPixel) {
357 GLushort pixel = data16[n];
358 rgba[n][RCOMP] = FX_rgb_scale_5[ pixel & 0x1f];
359 rgba[n][GCOMP] = FX_rgb_scale_5[(pixel >> 5) & 0x1f];
360 rgba[n][BCOMP] = FX_rgb_scale_5[(pixel >> 10) & 0x1f];
361 rgba[n][ACOMP] = (pixel & 0x8000) ? 255 : 0;
362 }
363
364 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
365 }
366 END_BOARD_LOCK();
367 }
368
369 /*
370 * Read a span of 32-bit RGB pixels. Note, we don't worry about cliprects
371 * since OpenGL says obscured pixels have undefined values.
372 */
373 static void read_R8G8B8_span (const GLcontext * ctx,
374 GLuint n,
375 GLint x, GLint y,
376 GLubyte rgba[][4])
377 {
378 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
379 BEGIN_BOARD_LOCK();
380 grLfbReadRegion(fxMesa->currentFB, x, fxMesa->height - 1 - y, n, 1, n * 4, rgba);
381 END_BOARD_LOCK();
382 }
383
384
385 /************************************************************************/
386 /***** Pixel functions *****/
387 /************************************************************************/
388
389 static void
390 fxDDWriteRGBAPixels(const GLcontext * ctx,
391 GLuint n, const GLint x[], const GLint y[],
392 CONST GLubyte rgba[][4], const GLubyte mask[])
393 {
394 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
395 GLuint i;
396 GLint bottom = fxMesa->height - 1;
397
398 if (MESA_VERBOSE & VERBOSE_DRIVER) {
399 fprintf(stderr, "fxmesa: fxDDWriteRGBAPixels(...)\n");
400 }
401
402 for (i = 0; i < n; i++)
403 if (mask[i])
404 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x[i], bottom - y[i],
405 1, 1, (void *) rgba[i]);
406 }
407
408 static void
409 fxDDWriteMonoRGBAPixels(const GLcontext * ctx,
410 GLuint n, const GLint x[], const GLint y[],
411 const GLchan color[4], const GLubyte mask[])
412 {
413 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
414 GLuint i;
415 GLint bottom = fxMesa->height - 1;
416 GrColor_t gColor = FXCOLOR4(color);
417
418 if (MESA_VERBOSE & VERBOSE_DRIVER) {
419 fprintf(stderr, "fxmesa: fxDDWriteMonoRGBAPixels(...)\n");
420 }
421
422 for (i = 0; i < n; i++)
423 if (mask[i])
424 writeRegionClipped(fxMesa, fxMesa->currentFB, x[i], bottom - y[i],
425 GR_LFB_SRC_FMT_8888, 1, 1, 0, (void *) &gColor);
426 }
427
428
429 static void
430 read_R5G6B5_pixels(const GLcontext * ctx,
431 GLuint n, const GLint x[], const GLint y[],
432 GLubyte rgba[][4], const GLubyte mask[])
433 {
434 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
435 GrLfbInfo_t info;
436 BEGIN_BOARD_LOCK();
437 if (grLfbLock(GR_LFB_READ_ONLY,
438 fxMesa->currentFB,
439 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
440 const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
441 const GLint winX = 0;
442 const GLint winY = fxMesa->height - 1;
443 GLuint i;
444 for (i = 0; i < n; i++) {
445 if (mask[i]) {
446 const GLushort *data16 = (const GLushort *) info.lfbPtr
447 + (winY - y[i]) * srcStride + (winX + x[i]);
448 const GLushort pixel = *data16;
449 rgba[i][RCOMP] = FX_PixelToR[pixel];
450 rgba[i][GCOMP] = FX_PixelToG[pixel];
451 rgba[i][BCOMP] = FX_PixelToB[pixel];
452 rgba[i][ACOMP] = 255;
453 }
454 }
455 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
456 }
457 END_BOARD_LOCK();
458 }
459
460
461 static void read_R5G5B5_pixels (const GLcontext * ctx,
462 GLuint n,
463 const GLint x[], const GLint y[],
464 GLubyte rgba[][4],
465 const GLubyte mask[])
466 {
467 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
468 GrLfbInfo_t info;
469 BEGIN_BOARD_LOCK();
470 if (grLfbLock(GR_LFB_READ_ONLY,
471 fxMesa->currentFB,
472 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
473 const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
474 const GLint winX = 0;
475 const GLint winY = fxMesa->height - 1;
476 GLuint i;
477 for (i = 0; i < n; i++) {
478 if (mask[i]) {
479 const GLushort *data16 = (const GLushort *) info.lfbPtr
480 + (winY - y[i]) * srcStride + (winX + x[i]);
481 const GLushort pixel = *data16;
482 rgba[i][RCOMP] = FX_rgb_scale_5[ pixel & 0x1f];
483 rgba[i][GCOMP] = FX_rgb_scale_5[(pixel >> 5) & 0x1f];
484 rgba[i][BCOMP] = FX_rgb_scale_5[(pixel >> 10) & 0x1f];
485 rgba[i][ACOMP] = (pixel & 0x8000) ? 255 : 0;
486 }
487 }
488 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
489 }
490 END_BOARD_LOCK();
491 }
492
493
494 static void
495 read_R8G8B8_pixels(const GLcontext * ctx,
496 GLuint n, const GLint x[], const GLint y[],
497 GLubyte rgba[][4], const GLubyte mask[])
498 {
499 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
500 GrLfbInfo_t info;
501 BEGIN_BOARD_LOCK();
502 if (grLfbLock(GR_LFB_READ_ONLY,
503 fxMesa->currentFB,
504 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
505 const GLint srcStride = info.strideInBytes / 4; /* stride in GLuints */
506 const GLint winX = 0;
507 const GLint winY = fxMesa->height - 1;
508 GLuint i;
509 for (i = 0; i < n; i++) {
510 if (mask[i]) {
511 const GLuint *data32 = (const GLuint *) info.lfbPtr
512 + (winY - y[i]) * srcStride + (winX + x[i]);
513 const GLuint pixel = *data32;
514 *(GLuint *)&rgba[i][0] = pixel;
515 }
516 }
517 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
518 }
519 END_BOARD_LOCK();
520 }
521
522
523
524 /************************************************************************/
525 /***** Depth functions *****/
526 /************************************************************************/
527
528 void
529 fxDDWriteDepthSpan(GLcontext * ctx,
530 GLuint n, GLint x, GLint y, const GLdepth depth[],
531 const GLubyte mask[])
532 {
533 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
534 GLint bottom = fxMesa->height - 1;
535
536 if (MESA_VERBOSE & VERBOSE_DRIVER) {
537 fprintf(stderr, "fxmesa: fxDDWriteDepthSpan(...)\n");
538 }
539
540
541 if (mask) {
542 GLint i;
543 for (i = 0; i < n; i++) {
544 if (mask[i]) {
545 GLshort d = depth[i];
546 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y,
547 GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d);
548 }
549 }
550 }
551 else {
552 GLushort depth16[MAX_WIDTH];
553 GLint i;
554 for (i = 0; i < n; i++) {
555 depth16[i] = depth[i];
556 }
557 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom - y,
558 GR_LFB_SRC_FMT_ZA16, n, 1, 0, (void *) depth16);
559 }
560 }
561
562
563 void
564 fxDDWriteDepth32Span(GLcontext * ctx,
565 GLuint n, GLint x, GLint y, const GLdepth depth[],
566 const GLubyte mask[])
567 {
568 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
569 GLint bottom = fxMesa->height - 1;
570 GLint i;
571
572 if (MESA_VERBOSE & VERBOSE_DRIVER) {
573 fprintf(stderr, "fxmesa: fxDDWriteDepth32Span(...)\n");
574 }
575
576
577 if (mask) {
578 for (i = 0; i < n; i++) {
579 if (mask[i]) {
580 GLuint d = depth[i] << 8;
581 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y,
582 GR_LFBWRITEMODE_Z32, 1, 1, 0, (void *) &d);
583 }
584 }
585 }
586 else {
587 GLuint depth32[MAX_WIDTH];
588 for (i = 0; i < n; i++) {
589 depth32[i] = depth[i] << 8;
590 }
591 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom - y,
592 GR_LFBWRITEMODE_Z32, n, 1, 0, (void *) depth32);
593 }
594 }
595
596
597 void
598 fxDDReadDepthSpan(GLcontext * ctx,
599 GLuint n, GLint x, GLint y, GLdepth depth[])
600 {
601 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
602 GLint bottom = fxMesa->height - 1;
603 GLushort depth16[MAX_WIDTH];
604 GLuint i;
605
606 if (MESA_VERBOSE & VERBOSE_DRIVER) {
607 fprintf(stderr, "fxmesa: fxDDReadDepthSpan(...)\n");
608 }
609
610 grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth16);
611 for (i = 0; i < n; i++) {
612 depth[i] = depth16[i];
613 }
614 }
615
616
617 void
618 fxDDReadDepth32Span(GLcontext * ctx,
619 GLuint n, GLint x, GLint y, GLdepth depth[])
620 {
621 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
622 GLint bottom = fxMesa->height - 1;
623
624 if (MESA_VERBOSE & VERBOSE_DRIVER) {
625 fprintf(stderr, "fxmesa: fxDDReadDepth32Span(...)\n");
626 }
627
628 grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth);
629 }
630
631
632
633 void
634 fxDDWriteDepthPixels(GLcontext * ctx,
635 GLuint n, const GLint x[], const GLint y[],
636 const GLdepth depth[], const GLubyte mask[])
637 {
638 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
639 GLint bottom = fxMesa->height - 1;
640 GLuint i;
641
642 if (MESA_VERBOSE & VERBOSE_DRIVER) {
643 fprintf(stderr, "fxmesa: fxDDWriteDepthPixels(...)\n");
644 }
645
646 for (i = 0; i < n; i++) {
647 if (mask[i]) {
648 int xpos = x[i];
649 int ypos = bottom - y[i];
650 GLushort d = depth[i];
651 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos,
652 GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d);
653 }
654 }
655 }
656
657
658 void
659 fxDDWriteDepth32Pixels(GLcontext * ctx,
660 GLuint n, const GLint x[], const GLint y[],
661 const GLdepth depth[], const GLubyte mask[])
662 {
663 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
664 GLint bottom = fxMesa->height - 1;
665 GLuint i;
666
667 if (MESA_VERBOSE & VERBOSE_DRIVER) {
668 fprintf(stderr, "fxmesa: fxDDWriteDepth32Pixels(...)\n");
669 }
670
671 for (i = 0; i < n; i++) {
672 if (mask[i]) {
673 int xpos = x[i];
674 int ypos = bottom - y[i];
675 GLuint d = depth[i] << 8;
676 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos,
677 GR_LFBWRITEMODE_Z32, 1, 1, 0, (void *) &d);
678 }
679 }
680 }
681
682
683 void
684 fxDDReadDepthPixels(GLcontext * ctx, GLuint n,
685 const GLint x[], const GLint y[], GLdepth depth[])
686 {
687 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
688 GLint bottom = fxMesa->height - 1;
689 GLuint i;
690
691 if (MESA_VERBOSE & VERBOSE_DRIVER) {
692 fprintf(stderr, "fxmesa: fxDDReadDepthPixels(...)\n");
693 }
694
695 for (i = 0; i < n; i++) {
696 int xpos = x[i];
697 int ypos = bottom - y[i];
698 GLushort d;
699 grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &d);
700 depth[i] = d;
701 }
702 }
703
704
705 void
706 fxDDReadDepth32Pixels(GLcontext * ctx, GLuint n,
707 const GLint x[], const GLint y[], GLdepth depth[])
708 {
709 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
710 GLint bottom = fxMesa->height - 1;
711 GLuint i;
712
713 if (MESA_VERBOSE & VERBOSE_DRIVER) {
714 fprintf(stderr, "fxmesa: fxDDReadDepth32Pixels(...)\n");
715 }
716
717 for (i = 0; i < n; i++) {
718 int xpos = x[i];
719 int ypos = bottom - y[i];
720 grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &depth[i]);
721 }
722 }
723
724
725
726 /* Set the buffer used for reading */
727 /* XXX support for separate read/draw buffers hasn't been tested */
728 static void
729 fxDDSetBuffer(GLcontext * ctx, GLframebuffer * buffer, GLuint bufferBit)
730 {
731 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
732 (void) buffer;
733
734 if (MESA_VERBOSE & VERBOSE_DRIVER) {
735 fprintf(stderr, "fxmesa: fxDDSetBuffer(%x)\n", (int) bufferBit);
736 }
737
738 if (bufferBit == FRONT_LEFT_BIT) {
739 fxMesa->currentFB = GR_BUFFER_FRONTBUFFER;
740 grRenderBuffer(fxMesa->currentFB);
741 }
742 else if (bufferBit == BACK_LEFT_BIT) {
743 fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
744 grRenderBuffer(fxMesa->currentFB);
745 }
746 }
747
748
749 /************************************************************************/
750
751
752
753 void
754 fxSetupDDSpanPointers(GLcontext * ctx)
755 {
756 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
757
758 swdd->SetBuffer = fxDDSetBuffer;
759
760 swdd->WriteRGBASpan = fxDDWriteRGBASpan;
761 swdd->WriteRGBSpan = fxDDWriteRGBSpan;
762 swdd->WriteMonoRGBASpan = fxDDWriteMonoRGBASpan;
763 swdd->WriteRGBAPixels = fxDDWriteRGBAPixels;
764 swdd->WriteMonoRGBAPixels = fxDDWriteMonoRGBAPixels;
765
766 /* swdd->ReadRGBASpan =fxDDReadRGBASpan; */
767 {
768 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
769 switch (fxMesa->colDepth) {
770 case 15:
771 swdd->ReadRGBASpan = read_R5G5B5_span;
772 swdd->ReadRGBAPixels = read_R5G5B5_pixels;
773 swdd->WriteDepthSpan = fxDDWriteDepthSpan;
774 swdd->WriteDepthPixels = fxDDWriteDepthPixels;
775 swdd->ReadDepthSpan = fxDDReadDepthSpan;
776 swdd->ReadDepthPixels = fxDDReadDepthPixels;
777 break;
778 case 16:
779 swdd->ReadRGBASpan = read_R5G6B5_span;
780 swdd->ReadRGBAPixels = read_R5G6B5_pixels;
781 swdd->WriteDepthSpan = fxDDWriteDepthSpan;
782 swdd->WriteDepthPixels = fxDDWriteDepthPixels;
783 swdd->ReadDepthSpan = fxDDReadDepthSpan;
784 swdd->ReadDepthPixels = fxDDReadDepthPixels;
785 break;
786 case 32:
787 swdd->ReadRGBASpan = read_R8G8B8_span;
788 swdd->ReadRGBAPixels = read_R8G8B8_pixels;
789 swdd->WriteDepthSpan = fxDDWriteDepth32Span;
790 swdd->WriteDepthPixels = fxDDWriteDepth32Pixels;
791 swdd->ReadDepthSpan = fxDDReadDepth32Span;
792 swdd->ReadDepthPixels = fxDDReadDepth32Pixels;
793 break;
794 }
795 }
796 }
797
798
799 #else
800
801
802 /*
803 * Need this to provide at least one external definition.
804 */
805
806 extern int gl_fx_dummy_function_span(void);
807 int
808 gl_fx_dummy_function_span(void)
809 {
810 return 0;
811 }
812
813 #endif /* FX */