fixed some configure;make build problems. cleaned-up copyright info.
[mesa.git] / src / mesa / drivers / glide / fxddspan.c
1 /* $Id: fxddspan.c,v 1.19 2001/09/23 16:50:01 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 4.0
6 *
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 /* Authors:
28 * David Bucciarelli
29 * Brian Paul
30 * Daryll Strauss
31 * Keith Whitwell
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 "swrast/swrast.h"
46
47 #ifdef _MSC_VER
48 #ifdef _WIN32
49 #pragma warning( disable : 4090 4022 )
50 /* 4101 : "different 'const' qualifier"
51 * 4022 : "pointer mistmatch for actual parameter 'n'
52 */
53 #endif
54 #endif
55
56
57 #if !defined(FXMESA_USE_ARGB)
58
59
60
61 #define writeRegionClipped(fxm,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \
62 FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)
63
64
65
66 /* KW: Rearranged the args in the call to grLfbWriteRegion().
67 */
68 #define LFB_WRITE_SPAN_MESA(dst_buffer, \
69 dst_x, \
70 dst_y, \
71 src_width, \
72 src_stride, \
73 src_data) \
74 writeRegionClipped(fxMesa, dst_buffer, \
75 dst_x, \
76 dst_y, \
77 GR_LFB_SRC_FMT_8888, \
78 src_width, \
79 1, \
80 src_stride, \
81 src_data) \
82
83
84 #else /* !defined(FXMESA_USE_RGBA) */
85
86 #define writeRegionClipped(fxm,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \
87 FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)
88
89
90 #define MESACOLOR_TO_ARGB(c) ( \
91 ( ((unsigned int)(c[ACOMP]))<<24 ) | \
92 ( ((unsigned int)(c[RCOMP]))<<16 ) | \
93 ( ((unsigned int)(c[GCOMP]))<<8 ) | \
94 ( (unsigned int)(c[BCOMP])) )
95
96 inline void
97 LFB_WRITE_SPAN_MESA(GrBuffer_t dst_buffer,
98 FxU32 dst_x,
99 FxU32 dst_y,
100 FxU32 src_width, FxI32 src_stride, void *src_data)
101 {
102 /* Covert to ARGB */
103 GLubyte(*rgba)[4] = src_data;
104 GLuint argb[MAX_WIDTH];
105 int i;
106
107 for (i = 0; i < src_width; i++) {
108 argb[i] = MESACOLOR_TO_ARGB(rgba[i]);
109 }
110 writeRegionClipped( /*fxMesa, */ NULL, dst_buffer,
111 dst_x,
112 dst_y,
113 GR_LFB_SRC_FMT_8888,
114 src_width, 1, src_stride, (void *) argb);
115 }
116
117 #endif /* !defined(FXMESA_USE_RGBA) */
118
119
120 /************************************************************************/
121 /***** Span functions *****/
122 /************************************************************************/
123
124
125 static void
126 fxDDWriteRGBASpan(const GLcontext * ctx,
127 GLuint n, GLint x, GLint y,
128 const GLubyte rgba[][4], const GLubyte mask[])
129 {
130 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
131 GLuint i;
132 GLint bottom = fxMesa->height - 1;
133
134 if (MESA_VERBOSE & VERBOSE_DRIVER) {
135 fprintf(stderr, "fxmesa: fxDDWriteRGBASpan(...)\n");
136 }
137
138 if (mask) {
139 int span = 0;
140
141 for (i = 0; i < n; i++) {
142 if (mask[i]) {
143 ++span;
144 }
145 else {
146 if (span > 0) {
147 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + i - span,
148 bottom - y,
149 /* GR_LFB_SRC_FMT_8888, */ span, /*1, */ 0,
150 (void *) rgba[i - span]);
151 span = 0;
152 }
153 }
154 }
155
156 if (span > 0)
157 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + n - span, bottom - y,
158 /* GR_LFB_SRC_FMT_8888, */ span, /*1, */ 0,
159 (void *) rgba[n - span]);
160 }
161 else
162 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x, bottom - y, /* GR_LFB_SRC_FMT_8888, */
163 n, /* 1, */ 0, (void *) rgba);
164 }
165
166
167 static void
168 fxDDWriteRGBSpan(const GLcontext * ctx,
169 GLuint n, GLint x, GLint y,
170 const GLubyte rgb[][3], const GLubyte mask[])
171 {
172 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
173 GLuint i;
174 GLint bottom = fxMesa->height - 1;
175 GLubyte rgba[MAX_WIDTH][4];
176
177 if (MESA_VERBOSE & VERBOSE_DRIVER) {
178 fprintf(stderr, "fxmesa: fxDDWriteRGBSpan()\n");
179 }
180
181 if (mask) {
182 int span = 0;
183
184 for (i = 0; i < n; i++) {
185 if (mask[i]) {
186 rgba[span][RCOMP] = rgb[i][0];
187 rgba[span][GCOMP] = rgb[i][1];
188 rgba[span][BCOMP] = rgb[i][2];
189 rgba[span][ACOMP] = 255;
190 ++span;
191 }
192 else {
193 if (span > 0) {
194 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + i - span,
195 bottom - y,
196 /*GR_LFB_SRC_FMT_8888, */ span, /* 1, */ 0,
197 (void *) rgba);
198 span = 0;
199 }
200 }
201 }
202
203 if (span > 0)
204 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + n - span, bottom - y,
205 /*GR_LFB_SRC_FMT_8888, */ span, /* 1, */ 0,
206 (void *) rgba);
207 }
208 else {
209 for (i = 0; i < n; i++) {
210 rgba[i][RCOMP] = rgb[i][0];
211 rgba[i][GCOMP] = rgb[i][1];
212 rgba[i][BCOMP] = rgb[i][2];
213 rgba[i][ACOMP] = 255;
214 }
215
216 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x, bottom - y, /* GR_LFB_SRC_FMT_8888, */
217 n, /* 1, */ 0, (void *) rgba);
218 }
219 }
220
221
222 static void
223 fxDDWriteMonoRGBASpan(const GLcontext * ctx,
224 GLuint n, GLint x, GLint y,
225 const GLchan color[4], const GLubyte mask[])
226 {
227 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
228 GLuint i;
229 GLint bottom = fxMesa->height - 1;
230 GLuint data[MAX_WIDTH];
231 GrColor_t gColor = FXCOLOR4(color);
232
233 if (MESA_VERBOSE & VERBOSE_DRIVER) {
234 fprintf(stderr, "fxmesa: fxDDWriteMonoRGBASpan(...)\n");
235 }
236
237 if (mask) {
238 int span = 0;
239
240 for (i = 0; i < n; i++) {
241 if (mask[i]) {
242 data[span] = (GLuint) gColor;
243 ++span;
244 }
245 else {
246 if (span > 0) {
247 writeRegionClipped(fxMesa, fxMesa->currentFB, x + i - span,
248 bottom - y, GR_LFB_SRC_FMT_8888, span, 1, 0,
249 (void *) data);
250 span = 0;
251 }
252 }
253 }
254
255 if (span > 0)
256 writeRegionClipped(fxMesa, fxMesa->currentFB, x + n - span,
257 bottom - y, GR_LFB_SRC_FMT_8888, span, 1, 0,
258 (void *) data);
259 }
260 else {
261 for (i = 0; i < n; i++) {
262 data[i] = (GLuint) gColor;
263 }
264
265 writeRegionClipped(fxMesa, fxMesa->currentFB, x, bottom - y,
266 GR_LFB_SRC_FMT_8888, n, 1, 0, (void *) data);
267 }
268 }
269
270
271 #if 0
272 static void
273 fxDDReadRGBASpan(const GLcontext * ctx,
274 GLuint n, GLint x, GLint y, GLubyte rgba[][4])
275 {
276 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
277 GLushort data[MAX_WIDTH];
278 GLuint i;
279 GLint bottom = fxMesa->height - 1;
280
281 printf("read span %d, %d, %d\n", x, y, n);
282 if (MESA_VERBOSE & VERBOSE_DRIVER) {
283 fprintf(stderr, "fxmesa: fxDDReadRGBASpan(...)\n");
284 }
285
286 assert(n < MAX_WIDTH);
287
288 FX_grLfbReadRegion(fxMesa->currentFB, x, bottom - y, n, 1, 0, data);
289
290 for (i = 0; i < n; i++) {
291 GLushort pixel = data[i];
292 rgba[i][RCOMP] = FX_PixelToR[pixel];
293 rgba[i][GCOMP] = FX_PixelToG[pixel];
294 rgba[i][BCOMP] = FX_PixelToB[pixel];
295 rgba[i][ACOMP] = 255;
296 }
297 }
298 #endif
299
300
301 /*
302 * Read a span of 16-bit RGB pixels. Note, we don't worry about cliprects
303 * since OpenGL says obscured pixels have undefined values.
304 */
305 static void
306 read_R5G6B5_span(const GLcontext * ctx,
307 GLuint n, GLint x, GLint y, GLubyte rgba[][4])
308 {
309 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
310 GrLfbInfo_t info;
311 BEGIN_BOARD_LOCK();
312 if (grLfbLock(GR_LFB_READ_ONLY,
313 fxMesa->currentFB,
314 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
315 const GLint winX = 0;
316 const GLint winY = fxMesa->height - 1;
317 const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
318 const GLushort *data16 = (const GLushort *) info.lfbPtr
319 + (winY - y) * srcStride + (winX + x);
320 const GLuint *data32 = (const GLuint *) data16;
321 GLuint i, j;
322 GLuint extraPixel = (n & 1);
323 n -= extraPixel;
324 for (i = j = 0; i < n; i += 2, j++) {
325 GLuint pixel = data32[j];
326 GLuint pixel0 = pixel & 0xffff;
327 GLuint pixel1 = pixel >> 16;
328 rgba[i][RCOMP] = FX_PixelToR[pixel0];
329 rgba[i][GCOMP] = FX_PixelToG[pixel0];
330 rgba[i][BCOMP] = FX_PixelToB[pixel0];
331 rgba[i][ACOMP] = 255;
332 rgba[i + 1][RCOMP] = FX_PixelToR[pixel1];
333 rgba[i + 1][GCOMP] = FX_PixelToG[pixel1];
334 rgba[i + 1][BCOMP] = FX_PixelToB[pixel1];
335 rgba[i + 1][ACOMP] = 255;
336 }
337 if (extraPixel) {
338 GLushort pixel = data16[n];
339 rgba[n][RCOMP] = FX_PixelToR[pixel];
340 rgba[n][GCOMP] = FX_PixelToG[pixel];
341 rgba[n][BCOMP] = FX_PixelToB[pixel];
342 rgba[n][ACOMP] = 255;
343 }
344
345 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
346 }
347 END_BOARD_LOCK();
348 }
349
350
351 /************************************************************************/
352 /***** Pixel functions *****/
353 /************************************************************************/
354
355 static void
356 fxDDWriteRGBAPixels(const GLcontext * ctx,
357 GLuint n, const GLint x[], const GLint y[],
358 CONST GLubyte rgba[][4], const GLubyte mask[])
359 {
360 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
361 GLuint i;
362 GLint bottom = fxMesa->height - 1;
363
364 if (MESA_VERBOSE & VERBOSE_DRIVER) {
365 fprintf(stderr, "fxmesa: fxDDWriteRGBAPixels(...)\n");
366 }
367
368 for (i = 0; i < n; i++)
369 if (mask[i])
370 LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x[i], bottom - y[i],
371 1, 1, (void *) rgba[i]);
372 }
373
374 static void
375 fxDDWriteMonoRGBAPixels(const GLcontext * ctx,
376 GLuint n, const GLint x[], const GLint y[],
377 const GLchan color[4], const GLubyte mask[])
378 {
379 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
380 GLuint i;
381 GLint bottom = fxMesa->height - 1;
382 GrColor_t gColor = FXCOLOR4(color);
383
384 if (MESA_VERBOSE & VERBOSE_DRIVER) {
385 fprintf(stderr, "fxmesa: fxDDWriteMonoRGBAPixels(...)\n");
386 }
387
388 for (i = 0; i < n; i++)
389 if (mask[i])
390 writeRegionClipped(fxMesa, fxMesa->currentFB, x[i], bottom - y[i],
391 GR_LFB_SRC_FMT_8888, 1, 1, 0, (void *) &gColor);
392 }
393
394
395 static void
396 read_R5G6B5_pixels(const GLcontext * ctx,
397 GLuint n, const GLint x[], const GLint y[],
398 GLubyte rgba[][4], const GLubyte mask[])
399 {
400 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
401 GrLfbInfo_t info;
402 BEGIN_BOARD_LOCK();
403 if (grLfbLock(GR_LFB_READ_ONLY,
404 fxMesa->currentFB,
405 GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
406 const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
407 const GLint winX = 0;
408 const GLint winY = fxMesa->height - 1;
409 GLuint i;
410 for (i = 0; i < n; i++) {
411 if (mask[i]) {
412 const GLushort *data16 = (const GLushort *) info.lfbPtr
413 + (winY - y[i]) * srcStride + (winX + x[i]);
414 const GLushort pixel = *data16;
415 rgba[i][RCOMP] = FX_PixelToR[pixel];
416 rgba[i][GCOMP] = FX_PixelToG[pixel];
417 rgba[i][BCOMP] = FX_PixelToB[pixel];
418 rgba[i][ACOMP] = 255;
419 }
420 }
421 grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
422 }
423 END_BOARD_LOCK();
424 }
425
426
427
428 /************************************************************************/
429 /***** Depth functions *****/
430 /************************************************************************/
431
432 void
433 fxDDWriteDepthSpan(GLcontext * ctx,
434 GLuint n, GLint x, GLint y, const GLdepth depth[],
435 const GLubyte mask[])
436 {
437 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
438 GLint bottom = fxMesa->height - 1;
439
440 if (MESA_VERBOSE & VERBOSE_DRIVER) {
441 fprintf(stderr, "fxmesa: fxDDWriteDepthSpan(...)\n");
442 }
443
444
445 if (mask) {
446 GLint i;
447 for (i = 0; i < n; i++) {
448 if (mask[i]) {
449 GLshort d = depth[i];
450 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y,
451 GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d);
452 }
453 }
454 }
455 else {
456 GLushort depth16[MAX_WIDTH];
457 GLint i;
458 for (i = 0; i < n; i++) {
459 depth16[i] = depth[i];
460 }
461 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom - y,
462 GR_LFB_SRC_FMT_ZA16, n, 1, 0, (void *) depth16);
463 }
464 }
465
466
467 void
468 fxDDReadDepthSpan(GLcontext * ctx,
469 GLuint n, GLint x, GLint y, GLdepth depth[])
470 {
471 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
472 GLint bottom = fxMesa->height - 1;
473 GLushort depth16[MAX_WIDTH];
474 GLuint i;
475
476 if (MESA_VERBOSE & VERBOSE_DRIVER) {
477 fprintf(stderr, "fxmesa: fxDDReadDepthSpan(...)\n");
478 }
479
480 FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth16);
481 for (i = 0; i < n; i++) {
482 depth[i] = depth16[i];
483 }
484 }
485
486
487
488 void
489 fxDDWriteDepthPixels(GLcontext * ctx,
490 GLuint n, const GLint x[], const GLint y[],
491 const GLdepth depth[], const GLubyte mask[])
492 {
493 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
494 GLint bottom = fxMesa->height - 1;
495 GLuint i;
496
497 if (MESA_VERBOSE & VERBOSE_DRIVER) {
498 fprintf(stderr, "fxmesa: fxDDWriteDepthPixels(...)\n");
499 }
500
501 for (i = 0; i < n; i++) {
502 if (mask[i]) {
503 int xpos = x[i];
504 int ypos = bottom - y[i];
505 GLushort d = depth[i];
506 writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos,
507 GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d);
508 }
509 }
510 }
511
512
513 void
514 fxDDReadDepthPixels(GLcontext * ctx, GLuint n,
515 const GLint x[], const GLint y[], GLdepth depth[])
516 {
517 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
518 GLint bottom = fxMesa->height - 1;
519 GLuint i;
520
521 if (MESA_VERBOSE & VERBOSE_DRIVER) {
522 fprintf(stderr, "fxmesa: fxDDReadDepthPixels(...)\n");
523 }
524
525 for (i = 0; i < n; i++) {
526 int xpos = x[i];
527 int ypos = bottom - y[i];
528 GLushort d;
529 FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &d);
530 depth[i] = d;
531 }
532 }
533
534
535
536 /* Set the buffer used for reading */
537 /* XXX support for separate read/draw buffers hasn't been tested */
538 static void
539 fxDDSetReadBuffer(GLcontext * ctx, GLframebuffer * buffer, GLenum mode)
540 {
541 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
542 (void) buffer;
543
544 if (MESA_VERBOSE & VERBOSE_DRIVER) {
545 fprintf(stderr, "fxmesa: fxDDSetBuffer(%x)\n", (int) mode);
546 }
547
548 if (mode == GL_FRONT_LEFT) {
549 fxMesa->currentFB = GR_BUFFER_FRONTBUFFER;
550 FX_grRenderBuffer(fxMesa->currentFB);
551 }
552 else if (mode == GL_BACK_LEFT) {
553 fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
554 FX_grRenderBuffer(fxMesa->currentFB);
555 }
556 }
557
558
559 /************************************************************************/
560
561
562
563 void
564 fxSetupDDSpanPointers(GLcontext * ctx)
565 {
566 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
567
568 swdd->SetReadBuffer = fxDDSetReadBuffer;
569
570 swdd->WriteRGBASpan = fxDDWriteRGBASpan;
571 swdd->WriteRGBSpan = fxDDWriteRGBSpan;
572 swdd->WriteMonoRGBASpan = fxDDWriteMonoRGBASpan;
573 swdd->WriteRGBAPixels = fxDDWriteRGBAPixels;
574 swdd->WriteMonoRGBAPixels = fxDDWriteMonoRGBAPixels;
575
576 swdd->WriteDepthSpan = fxDDWriteDepthSpan;
577 swdd->WriteDepthPixels = fxDDWriteDepthPixels;
578 swdd->ReadDepthSpan = fxDDReadDepthSpan;
579 swdd->ReadDepthPixels = fxDDReadDepthPixels;
580
581 /* swdd->ReadRGBASpan =fxDDReadRGBASpan; */
582 swdd->ReadRGBASpan = read_R5G6B5_span;
583 swdd->ReadRGBAPixels = read_R5G6B5_pixels;
584 }
585
586
587 #else
588
589
590 /*
591 * Need this to provide at least one external definition.
592 */
593
594 extern int gl_fx_dummy_function_span(void);
595 int
596 gl_fx_dummy_function_span(void)
597 {
598 return 0;
599 }
600
601 #endif /* FX */