1 /* -*- mode: C; tab-width:8; -*-
3 fxdd.c - 3Dfx VooDoo Mesa span and pixel functions
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * See the file fxapi.c for more informations about authors
35 #pragma warning( disable : 4090 4022 )
36 /* 4101 : "different 'const' qualifier"
37 * 4022 : "pointer mistmatch for actual parameter 'n'
43 #if !defined(FXMESA_USE_ARGB)
45 #define LFB_WRITE_SPAN_MESA(dst_buffer,dst_x,dst_y,src_width,src_stride,src_data) \
46 grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_width,1,GR_LFB_SRC_FMT_8888,src_stride,src_data)
47 #else /* defined(FXMESA_USE_RGBA) */
49 #define MESACOLOR_TO_ARGB(c) ( \
50 ( ((unsigned int)(c[ACOMP]))<<24 ) | \
51 ( ((unsigned int)(c[RCOMP]))<<16 ) | \
52 ( ((unsigned int)(c[GCOMP]))<<8 ) | \
53 ( (unsigned int)(c[BCOMP])) )
55 /* inline */ void LFB_WRITE_SPAN_MESA(GrBuffer_t dst_buffer
,
56 FxU32 dst_x
, FxU32 dst_y
,
57 /* GrLfbSrcFmt_t src_format, format is GR_LFB_SRC_FMT_8888 */
58 FxU32 src_width
,/* FxU32 src_height, height is 1 */
59 FxI32 src_stride
, void *src_data
)
62 GLubyte (*rgba
)[4] = src_data
;
63 GLuint argb
[MAX_WIDTH
];
66 for (i
= 0; i
< src_width
; i
++)
68 argb
[i
] = MESACOLOR_TO_ARGB(rgba
[i
]);
70 FX_grLfbWriteRegion(dst_buffer
,dst_x
,dst_y
,GR_LFB_SRC_FMT_8888
,src_width
,1,src_stride
,(void*)argb
);
74 /************************************************************************/
75 /***** Span functions *****/
76 /************************************************************************/
78 static void fxDDWriteRGBASpan(const GLcontext
*ctx
,
79 GLuint n
, GLint x
, GLint y
,
80 const GLubyte rgba
[][4], const GLubyte mask
[])
82 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
84 GLint bottom
=fxMesa
->height
-1;
86 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
87 fprintf(stderr
,"fxmesa: fxDDWriteRGBASpan(...)\n");
98 LFB_WRITE_SPAN_MESA( fxMesa
->currentFB
, x
+i
-span
, bottom
-y
,
99 /* GR_LFB_SRC_FMT_8888,*/ span
, /*1,*/ 0, (void *) rgba
[i
-span
] );
106 LFB_WRITE_SPAN_MESA( fxMesa
->currentFB
, x
+n
-span
, bottom
-y
,
107 /* GR_LFB_SRC_FMT_8888, */ span
, /*1,*/ 0, (void *) rgba
[n
-span
] );
109 LFB_WRITE_SPAN_MESA( fxMesa
->currentFB
, x
, bottom
-y
,/* GR_LFB_SRC_FMT_8888,*/
110 n
,/* 1,*/ 0, (void *) rgba
);
114 static void fxDDWriteRGBSpan(const GLcontext
*ctx
,
115 GLuint n
, GLint x
, GLint y
,
116 const GLubyte rgb
[][3], const GLubyte mask
[])
118 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
120 GLint bottom
=fxMesa
->height
-1;
121 GLubyte rgba
[MAX_WIDTH
][4];
123 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
124 fprintf(stderr
,"fxmesa: fxDDWriteRGBSpan()\n");
132 rgba
[span
][RCOMP
] = rgb
[i
][0];
133 rgba
[span
][GCOMP
] = rgb
[i
][1];
134 rgba
[span
][BCOMP
] = rgb
[i
][2];
135 rgba
[span
][ACOMP
] = 255;
139 LFB_WRITE_SPAN_MESA( fxMesa
->currentFB
, x
+i
-span
, bottom
-y
,
140 /*GR_LFB_SRC_FMT_8888,*/ span
,/* 1,*/ 0, (void *) rgba
);
147 LFB_WRITE_SPAN_MESA( fxMesa
->currentFB
, x
+n
-span
, bottom
-y
,
148 /*GR_LFB_SRC_FMT_8888,*/ span
,/* 1,*/ 0, (void *) rgba
);
151 rgba
[i
][RCOMP
]=rgb
[i
][0];
152 rgba
[i
][GCOMP
]=rgb
[i
][1];
153 rgba
[i
][BCOMP
]=rgb
[i
][2];
157 LFB_WRITE_SPAN_MESA( fxMesa
->currentFB
, x
, bottom
-y
,/* GR_LFB_SRC_FMT_8888,*/
158 n
,/* 1,*/ 0, (void *) rgba
);
163 static void fxDDWriteMonoRGBASpan(const GLcontext
*ctx
,
164 GLuint n
, GLint x
, GLint y
,
165 const GLubyte mask
[])
167 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
169 GLint bottom
=fxMesa
->height
-1;
170 GLuint data
[MAX_WIDTH
];
172 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
173 fprintf(stderr
,"fxmesa: fxDDWriteMonoRGBASpan(...)\n");
181 data
[span
] = (GLuint
) fxMesa
->color
;
185 FX_grLfbWriteRegion( fxMesa
->currentFB
, x
+i
-span
, bottom
-y
,
186 GR_LFB_SRC_FMT_8888
, span
, 1, 0,
194 FX_grLfbWriteRegion( fxMesa
->currentFB
, x
+n
-span
, bottom
-y
,
195 GR_LFB_SRC_FMT_8888
, span
, 1, 0,
199 data
[i
]=(GLuint
) fxMesa
->color
;
202 FX_grLfbWriteRegion( fxMesa
->currentFB
, x
, bottom
-y
, GR_LFB_SRC_FMT_8888
,
203 n
, 1, 0, (void *) data
);
208 static void fxDDReadRGBASpan(const GLcontext
*ctx
,
209 GLuint n
, GLint x
, GLint y
, GLubyte rgba
[][4])
211 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
212 GLushort data
[MAX_WIDTH
];
214 GLint bottom
=fxMesa
->height
-1;
216 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
217 fprintf(stderr
,"fxmesa: fxDDReadRGBASpan(...)\n");
220 assert(n
< MAX_WIDTH
);
222 grLfbReadRegion( fxMesa
->currentFB
, x
, bottom
-y
, n
, 1, 0, data
);
225 rgba
[i
][RCOMP
]=(data
[i
] & 0xF800) >> 8;
226 rgba
[i
][GCOMP
]=(data
[i
] & 0x07E0) >> 3;
227 rgba
[i
][BCOMP
]=(data
[i
] & 0x001F) << 3;
229 rgba
[i
][RCOMP
]=(data
[i
] & 0x001f) << 3;
230 rgba
[i
][GCOMP
]=(data
[i
] & 0x07e0) >> 3;
231 rgba
[i
][BCOMP
]=(data
[i
] & 0xf800) >> 8;
238 /************************************************************************/
239 /***** Pixel functions *****/
240 /************************************************************************/
242 static void fxDDWriteRGBAPixels(const GLcontext
*ctx
,
243 GLuint n
, const GLint x
[], const GLint y
[],
244 CONST GLubyte rgba
[][4], const GLubyte mask
[])
246 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
248 GLint bottom
=fxMesa
->height
-1;
250 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
251 fprintf(stderr
,"fxmesa: fxDDWriteRGBAPixels(...)\n");
256 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
,x
[i
],bottom
-y
[i
],
257 /*GR_LFB_SRC_FMT_8888,*/1,/*1,*/0,(void *)rgba
[i
]);
260 static void fxDDWriteMonoRGBAPixels(const GLcontext
*ctx
,
261 GLuint n
, const GLint x
[], const GLint y
[],
262 const GLubyte mask
[])
264 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
266 GLint bottom
=fxMesa
->height
-1;
268 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
269 fprintf(stderr
,"fxmesa: fxDDWriteMonoRGBAPixels(...)\n");
274 FX_grLfbWriteRegion(fxMesa
->currentFB
,x
[i
],bottom
-y
[i
],
275 GR_LFB_SRC_FMT_8888
,1,1,0,(void *) &fxMesa
->color
);
278 static void fxDDReadRGBAPixels(const GLcontext
*ctx
,
279 GLuint n
, const GLint x
[], const GLint y
[],
280 GLubyte rgba
[][4], const GLubyte mask
[])
282 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
284 GLint bottom
=fxMesa
->height
-1;
287 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
288 fprintf(stderr
,"fxmesa: fxDDReadRGBAPixels(...)\n");
293 grLfbReadRegion(fxMesa
->currentFB
,x
[i
],bottom
-y
[i
],1,1,0,&data
);
295 rgba
[i
][RCOMP
]=(data
& 0xF800) >> 8;
296 rgba
[i
][GCOMP
]=(data
& 0x07E0) >> 3;
297 rgba
[i
][BCOMP
]=(data
& 0x001F) >> 8;
299 rgba
[i
][RCOMP
]=(data
& 0x001f) << 3;
300 rgba
[i
][GCOMP
]=(data
& 0x07e0) >> 3;
301 rgba
[i
][BCOMP
]=(data
& 0xf800) >> 8;
303 /* the alpha value should be read from the auxiliary buffer when required */
309 /************************************************************************/
310 /***** Depth functions *****/
311 /************************************************************************/
313 void fxDDReadDepthSpanFloat(GLcontext
*ctx
,
314 GLuint n
, GLint x
, GLint y
, GLfloat depth
[])
316 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
318 GLint bottom
=fxMesa
->height
-1;
319 GLushort data
[MAX_WIDTH
];
321 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
322 fprintf(stderr
,"fxmesa: fxDDReadDepthSpanFloat(...)\n");
325 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
,bottom
-y
,n
,1,0,data
);
328 convert the read values to float values [0.0 .. 1.0].
331 depth
[i
]=data
[i
]/65535.0f
;
334 void fxDDReadDepthSpanInt(GLcontext
*ctx
,
335 GLuint n
, GLint x
, GLint y
, GLdepth depth
[])
337 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
338 GLint bottom
=fxMesa
->height
-1;
340 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
341 fprintf(stderr
,"fxmesa: fxDDReadDepthSpanInt(...)\n");
344 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
,bottom
-y
,n
,1,0,depth
);
347 GLuint
fxDDDepthTestSpanGeneric(GLcontext
*ctx
,
348 GLuint n
, GLint x
, GLint y
, const GLdepth z
[],
351 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
352 GLushort depthdata
[MAX_WIDTH
];
353 GLdepth
*zptr
=depthdata
;
357 GLint bottom
=fxMesa
->height
-1;
359 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
360 fprintf(stderr
,"fxmesa: fxDDDepthTestSpanGeneric(...)\n");
363 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
,bottom
-y
,n
,1,0,depthdata
);
365 /* switch cases ordered from most frequent to less frequent */
366 switch (ctx
->Depth
.Func
) {
368 if (ctx
->Depth
.Mask
) {
369 /* Update Z buffer */
370 for (i
=0; i
<n
; i
++,zptr
++,m
++) {
383 /* Don't update Z buffer */
384 for (i
=0; i
<n
; i
++,zptr
++,m
++) {
397 if (ctx
->Depth
.Mask
) {
398 /* Update Z buffer */
399 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
410 /* Don't update Z buffer */
411 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
424 if (ctx
->Depth
.Mask
) {
425 /* Update Z buffer */
426 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
437 /* Don't update Z buffer */
438 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
451 if (ctx
->Depth
.Mask
) {
452 /* Update Z buffer */
453 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
464 /* Don't update Z buffer */
465 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
478 if (ctx
->Depth
.Mask
) {
479 /* Update Z buffer */
480 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
491 /* Don't update Z buffer */
492 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
505 if (ctx
->Depth
.Mask
) {
506 /* Update Z buffer */
507 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
518 /* Don't update Z buffer */
519 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
532 if (ctx
->Depth
.Mask
) {
533 /* Update Z buffer */
534 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
541 /* Don't update Z buffer or mask */
555 FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER
,x
,bottom
-y
,GR_LFB_SRC_FMT_ZA16
,n
,1,0,depthdata
);
560 void fxDDDepthTestPixelsGeneric(GLcontext
* ctx
,
561 GLuint n
, const GLint x
[], const GLint y
[],
562 const GLdepth z
[], GLubyte mask
[])
564 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
567 GLint bottom
=fxMesa
->height
-1;
569 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
570 fprintf(stderr
,"fxmesa: fxDDDepthTestPixelsGeneric(...)\n");
573 /* switch cases ordered from most frequent to less frequent */
574 switch (ctx
->Depth
.Func
) {
576 if (ctx
->Depth
.Mask
) {
577 /* Update Z buffer */
578 for (i
=0; i
<n
; i
++) {
580 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],1,1,0,&zval
);
583 FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],GR_LFB_SRC_FMT_ZA16
,1,1,0,(void*)&z
[i
]);
591 /* Don't update Z buffer */
592 for (i
=0; i
<n
; i
++) {
594 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],1,1,0,&zval
);
607 if (ctx
->Depth
.Mask
) {
608 /* Update Z buffer */
609 for (i
=0; i
<n
; i
++) {
611 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],1,1,0,&zval
);
614 FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],GR_LFB_SRC_FMT_ZA16
,1,1,0,(void*)&z
[i
]);
622 /* Don't update Z buffer */
623 for (i
=0; i
<n
; i
++) {
625 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],1,1,0,&zval
);
637 if (ctx
->Depth
.Mask
) {
638 /* Update Z buffer */
639 for (i
=0; i
<n
; i
++) {
641 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],1,1,0,&zval
);
644 FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],GR_LFB_SRC_FMT_ZA16
,1,1,0,(void*)&z
[i
]);
652 /* Don't update Z buffer */
653 for (i
=0; i
<n
; i
++) {
655 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],1,1,0,&zval
);
667 if (ctx
->Depth
.Mask
) {
668 /* Update Z buffer */
669 for (i
=0; i
<n
; i
++) {
671 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],1,1,0,&zval
);
674 FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],GR_LFB_SRC_FMT_ZA16
,1,1,0,(void*)&z
[i
]);
682 /* Don't update Z buffer */
683 for (i
=0; i
<n
; i
++) {
685 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],1,1,0,&zval
);
697 if (ctx
->Depth
.Mask
) {
698 /* Update Z buffer */
699 for (i
=0; i
<n
; i
++) {
701 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],1,1,0,&zval
);
704 FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],GR_LFB_SRC_FMT_ZA16
,1,1,0,(void*)&z
[i
]);
712 /* Don't update Z buffer */
713 for (i
=0; i
<n
; i
++) {
715 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],1,1,0,&zval
);
728 if (ctx
->Depth
.Mask
) {
729 /* Update Z buffer */
730 for (i
=0; i
<n
; i
++) {
732 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],1,1,0,&zval
);
735 FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],GR_LFB_SRC_FMT_ZA16
,1,1,0,(void*)&z
[i
]);
743 /* Don't update Z buffer */
744 for (i
=0; i
<n
; i
++) {
746 grLfbReadRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],1,1,0,&zval
);
758 if (ctx
->Depth
.Mask
) {
759 /* Update Z buffer */
760 for (i
=0; i
<n
; i
++) {
762 FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER
,x
[i
],bottom
-y
[i
],GR_LFB_SRC_FMT_ZA16
,1,1,0,(void*)&z
[i
]);
766 /* Don't update Z buffer or mask */
770 /* depth test never passes */
780 /************************************************************************/
783 void fxSetupDDSpanPointers(GLcontext
*ctx
)
785 ctx
->Driver
.WriteRGBASpan
=fxDDWriteRGBASpan
;
786 ctx
->Driver
.WriteRGBSpan
=fxDDWriteRGBSpan
;
787 ctx
->Driver
.WriteMonoRGBASpan
=fxDDWriteMonoRGBASpan
;
788 ctx
->Driver
.WriteRGBAPixels
=fxDDWriteRGBAPixels
;
789 ctx
->Driver
.WriteMonoRGBAPixels
=fxDDWriteMonoRGBAPixels
;
791 ctx
->Driver
.WriteCI8Span
=NULL
;
792 ctx
->Driver
.WriteCI32Span
=NULL
;
793 ctx
->Driver
.WriteMonoCISpan
=NULL
;
794 ctx
->Driver
.WriteCI32Pixels
=NULL
;
795 ctx
->Driver
.WriteMonoCIPixels
=NULL
;
797 ctx
->Driver
.ReadRGBASpan
=fxDDReadRGBASpan
;
798 ctx
->Driver
.ReadRGBAPixels
=fxDDReadRGBAPixels
;
800 ctx
->Driver
.ReadCI32Span
=NULL
;
801 ctx
->Driver
.ReadCI32Pixels
=NULL
;
809 * Need this to provide at least one external definition.
812 int gl_fx_dummy_function_span(void)