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