1 /* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
27 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
30 * Thank you for your contribution, David!
32 * Please make note of the above copyright/license statement. If you
33 * contributed code or bug fixes to this code under the previous (GNU
34 * Library) license and object to the new license, your code will be
35 * removed at your request. Please see the Mesa docs/COPYRIGHT file
36 * for more information.
38 * Additional Mesa/3Dfx driver developers:
39 * Daryll Strauss <daryll@precisioninsight.com>
40 * Keith Whitwell <keith@precisioninsight.com>
42 * See fxapi.h for more revision/author details.
46 /* fxdd.c - 3Dfx VooDoo Mesa span and pixel functions */
59 #pragma warning( disable : 4090 4022 )
60 /* 4101 : "different 'const' qualifier"
61 * 4022 : "pointer mistmatch for actual parameter 'n'
67 #if !defined(FXMESA_USE_ARGB)
70 #if defined(FX_GLIDE3) && defined(XF86DRI)
72 static FxBool
writeRegionClipped(fxMesaContext fxMesa
, GrBuffer_t dst_buffer
,
73 FxU32 dst_x
, FxU32 dst_y
, GrLfbSrcFmt_t src_format
,
74 FxU32 src_width
, FxU32 src_height
, FxI32 src_stride
,
80 if (src_width
==1 && src_height
==1) { /* Easy case writing a point */
81 for (i
=0; i
<fxMesa
->numClipRects
; i
++) {
82 if ((dst_x
>=fxMesa
->pClipRects
[i
].x1
) &&
83 (dst_x
<fxMesa
->pClipRects
[i
].x2
) &&
84 (dst_y
>=fxMesa
->pClipRects
[i
].y1
) &&
85 (dst_y
<fxMesa
->pClipRects
[i
].y2
)) {
86 FX_grLfbWriteRegion(dst_buffer
, dst_x
, dst_y
, src_format
,
87 1, 1, src_stride
, src_data
);
91 } else if (src_height
==1) { /* Writing a span */
92 if (src_format
==GR_LFB_SRC_FMT_8888
) srcElt
=4;
93 else if (src_format
==GR_LFB_SRC_FMT_ZA16
) srcElt
=2;
95 fprintf(stderr
, "Unknown src_format passed to writeRegionClipped\n");
98 for (i
=0; i
<fxMesa
->numClipRects
; i
++) {
99 if (dst_y
>=fxMesa
->pClipRects
[i
].y1
&& dst_y
<fxMesa
->pClipRects
[i
].y2
) {
100 if (dst_x
<fxMesa
->pClipRects
[i
].x1
) {
101 x
=fxMesa
->pClipRects
[i
].x1
;
102 data
=((char*)src_data
)+srcElt
*(x
- dst_x
);
103 w
=src_width
-(x
-dst_x
);
109 if (x
+w
>fxMesa
->pClipRects
[i
].x2
) {
110 w
=fxMesa
->pClipRects
[i
].x2
-x
;
112 FX_grLfbWriteRegion(dst_buffer
, x
, dst_y
, src_format
, w
, 1,
116 } else { /* Punt on the case of arbitrary rectangles */
124 #define writeRegionClipped(fxm,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \
125 FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)
130 /* KW: Rearranged the args in the call to grLfbWriteRegion().
132 #define LFB_WRITE_SPAN_MESA(dst_buffer, \
138 writeRegionClipped(fxMesa, dst_buffer, \
141 GR_LFB_SRC_FMT_8888, \
148 #else /* !defined(FXMESA_USE_RGBA) */
150 #define writeRegionClipped(fxm,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \
151 FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)
154 #define MESACOLOR_TO_ARGB(c) ( \
155 ( ((unsigned int)(c[ACOMP]))<<24 ) | \
156 ( ((unsigned int)(c[RCOMP]))<<16 ) | \
157 ( ((unsigned int)(c[GCOMP]))<<8 ) | \
158 ( (unsigned int)(c[BCOMP])) )
160 inline void LFB_WRITE_SPAN_MESA(GrBuffer_t dst_buffer
,
168 GLubyte (*rgba
)[4] = src_data
;
169 GLuint argb
[MAX_WIDTH
];
172 for (i
= 0; i
< src_width
; i
++)
174 argb
[i
] = MESACOLOR_TO_ARGB(rgba
[i
]);
176 writeRegionClipped( /*fxMesa,*/ NULL
, dst_buffer
,
186 #endif /* !defined(FXMESA_USE_RGBA) */
189 /************************************************************************/
190 /***** Span functions *****/
191 /************************************************************************/
194 static void fxDDWriteRGBASpan(const GLcontext
*ctx
,
195 GLuint n
, GLint x
, GLint y
,
196 const GLubyte rgba
[][4], const GLubyte mask
[])
198 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
200 GLint bottom
=fxMesa
->height
+fxMesa
->y_offset
-1;
202 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
203 fprintf(stderr
,"fxmesa: fxDDWriteRGBASpan(...)\n");
215 LFB_WRITE_SPAN_MESA( fxMesa
->currentFB
, x
+i
-span
, bottom
-y
,
216 /* GR_LFB_SRC_FMT_8888,*/ span
, /*1,*/ 0, (void *) rgba
[i
-span
] );
223 LFB_WRITE_SPAN_MESA( fxMesa
->currentFB
, x
+n
-span
, bottom
-y
,
224 /* GR_LFB_SRC_FMT_8888, */ span
, /*1,*/ 0, (void *) rgba
[n
-span
] );
226 LFB_WRITE_SPAN_MESA( fxMesa
->currentFB
, x
, bottom
-y
,/* GR_LFB_SRC_FMT_8888,*/
227 n
,/* 1,*/ 0, (void *) rgba
);
231 static void fxDDWriteRGBSpan(const GLcontext
*ctx
,
232 GLuint n
, GLint x
, GLint y
,
233 const GLubyte rgb
[][3], const GLubyte mask
[])
235 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
237 GLint bottom
=fxMesa
->height
+fxMesa
->y_offset
-1;
238 GLubyte rgba
[MAX_WIDTH
][4];
240 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
241 fprintf(stderr
,"fxmesa: fxDDWriteRGBSpan()\n");
250 rgba
[span
][RCOMP
] = rgb
[i
][0];
251 rgba
[span
][GCOMP
] = rgb
[i
][1];
252 rgba
[span
][BCOMP
] = rgb
[i
][2];
253 rgba
[span
][ACOMP
] = 255;
257 LFB_WRITE_SPAN_MESA( fxMesa
->currentFB
, x
+i
-span
, bottom
-y
,
258 /*GR_LFB_SRC_FMT_8888,*/ span
,/* 1,*/ 0, (void *) rgba
);
265 LFB_WRITE_SPAN_MESA( fxMesa
->currentFB
, x
+n
-span
, bottom
-y
,
266 /*GR_LFB_SRC_FMT_8888,*/ span
,/* 1,*/ 0, (void *) rgba
);
269 rgba
[i
][RCOMP
]=rgb
[i
][0];
270 rgba
[i
][GCOMP
]=rgb
[i
][1];
271 rgba
[i
][BCOMP
]=rgb
[i
][2];
275 LFB_WRITE_SPAN_MESA( fxMesa
->currentFB
, x
, bottom
-y
,/* GR_LFB_SRC_FMT_8888,*/
276 n
,/* 1,*/ 0, (void *) rgba
);
281 static void fxDDWriteMonoRGBASpan(const GLcontext
*ctx
,
282 GLuint n
, GLint x
, GLint y
,
283 const GLubyte mask
[])
285 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
287 GLint bottom
=fxMesa
->height
+fxMesa
->y_offset
-1;
288 GLuint data
[MAX_WIDTH
];
290 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
291 fprintf(stderr
,"fxmesa: fxDDWriteMonoRGBASpan(...)\n");
300 data
[span
] = (GLuint
) fxMesa
->color
;
304 writeRegionClipped(fxMesa
, fxMesa
->currentFB
, x
+i
-span
, bottom
-y
,
305 GR_LFB_SRC_FMT_8888
, span
, 1, 0,
313 writeRegionClipped(fxMesa
, fxMesa
->currentFB
, x
+n
-span
, bottom
-y
,
314 GR_LFB_SRC_FMT_8888
, span
, 1, 0,
318 data
[i
]=(GLuint
) fxMesa
->color
;
321 writeRegionClipped(fxMesa
, fxMesa
->currentFB
, x
, bottom
-y
, GR_LFB_SRC_FMT_8888
,
322 n
, 1, 0, (void *) data
);
328 static void fxDDReadRGBASpan(const GLcontext
*ctx
,
329 GLuint n
, GLint x
, GLint y
, GLubyte rgba
[][4])
331 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
332 GLushort data
[MAX_WIDTH
];
334 GLint bottom
=fxMesa
->height
+fxMesa
->y_offset
-1;
336 printf("read span %d, %d, %d\n", x
,y
,n
);
337 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
338 fprintf(stderr
,"fxmesa: fxDDReadRGBASpan(...)\n");
341 assert(n
< MAX_WIDTH
);
344 FX_grLfbReadRegion( fxMesa
->currentFB
, x
, bottom
-y
, n
, 1, 0, data
);
347 GLushort pixel
= data
[i
];
348 rgba
[i
][RCOMP
] = FX_PixelToR
[pixel
];
349 rgba
[i
][GCOMP
] = FX_PixelToG
[pixel
];
350 rgba
[i
][BCOMP
] = FX_PixelToB
[pixel
];
351 rgba
[i
][ACOMP
] = 255;
358 * Read a span of 16-bit RGB pixels. Note, we don't worry about cliprects
359 * since OpenGL says obscured pixels have undefined values.
361 static void read_R5G6B5_span(const GLcontext
*ctx
,
362 GLuint n
, GLint x
, GLint y
, GLubyte rgba
[][4])
364 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
367 if (grLfbLock(GR_LFB_READ_ONLY
,
370 GR_ORIGIN_UPPER_LEFT
,
373 const GLint winX
= fxMesa
->x_offset
;
374 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
376 const GLint srcStride
= (fxMesa
->glCtx
->Color
.DrawBuffer
== GL_FRONT
)
377 ? (fxMesa
->screen_width
) : (info
.strideInBytes
/ 2);
379 const GLint srcStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
381 const GLushort
*data16
= (const GLushort
*) info
.lfbPtr
382 + (winY
- y
) * srcStride
384 const GLuint
*data32
= (const GLuint
*) data16
;
386 GLuint extraPixel
= (n
& 1);
388 for (i
= j
= 0; i
< n
; i
+= 2, j
++) {
389 GLuint pixel
= data32
[j
];
390 GLuint pixel0
= pixel
& 0xffff;
391 GLuint pixel1
= pixel
>> 16;
392 rgba
[i
][RCOMP
] = FX_PixelToR
[pixel0
];
393 rgba
[i
][GCOMP
] = FX_PixelToG
[pixel0
];
394 rgba
[i
][BCOMP
] = FX_PixelToB
[pixel0
];
395 rgba
[i
][ACOMP
] = 255;
396 rgba
[i
+1][RCOMP
] = FX_PixelToR
[pixel1
];
397 rgba
[i
+1][GCOMP
] = FX_PixelToG
[pixel1
];
398 rgba
[i
+1][BCOMP
] = FX_PixelToB
[pixel1
];
399 rgba
[i
+1][ACOMP
] = 255;
402 GLushort pixel
= data16
[n
];
403 rgba
[n
][RCOMP
] = FX_PixelToR
[pixel
];
404 rgba
[n
][GCOMP
] = FX_PixelToG
[pixel
];
405 rgba
[n
][BCOMP
] = FX_PixelToB
[pixel
];
406 rgba
[n
][ACOMP
] = 255;
409 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
415 /************************************************************************/
416 /***** Pixel functions *****/
417 /************************************************************************/
419 static void fxDDWriteRGBAPixels(const GLcontext
*ctx
,
420 GLuint n
, const GLint x
[], const GLint y
[],
421 CONST GLubyte rgba
[][4], const GLubyte mask
[])
423 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
425 GLint bottom
=fxMesa
->height
+fxMesa
->y_offset
-1;
427 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
428 fprintf(stderr
,"fxmesa: fxDDWriteRGBAPixels(...)\n");
433 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
[i
]+fxMesa
->x_offset
, bottom
-y
[i
],
434 1, 1, (void *)rgba
[i
]);
437 static void fxDDWriteMonoRGBAPixels(const GLcontext
*ctx
,
438 GLuint n
, const GLint x
[], const GLint y
[],
439 const GLubyte mask
[])
441 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
443 GLint bottom
=fxMesa
->height
+fxMesa
->y_offset
-1;
445 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
446 fprintf(stderr
,"fxmesa: fxDDWriteMonoRGBAPixels(...)\n");
451 writeRegionClipped(fxMesa
, fxMesa
->currentFB
,x
[i
]+fxMesa
->x_offset
,bottom
-y
[i
],
452 GR_LFB_SRC_FMT_8888
,1,1,0,(void *) &fxMesa
->color
);
456 static void read_R5G6B5_pixels(const GLcontext
*ctx
,
457 GLuint n
, const GLint x
[], const GLint y
[],
458 GLubyte rgba
[][4], const GLubyte mask
[])
460 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
463 if (grLfbLock(GR_LFB_READ_ONLY
,
466 GR_ORIGIN_UPPER_LEFT
,
470 const GLint srcStride
= (fxMesa
->glCtx
->Color
.DrawBuffer
== GL_FRONT
)
471 ? (fxMesa
->screen_width
) : (info
.strideInBytes
/ 2);
473 const GLint srcStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
475 const GLint winX
= fxMesa
->x_offset
;
476 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
480 const GLushort
*data16
= (const GLushort
*) info
.lfbPtr
481 + (winY
- y
[i
]) * srcStride
483 const GLushort pixel
= *data16
;
484 rgba
[i
][RCOMP
] = FX_PixelToR
[pixel
];
485 rgba
[i
][GCOMP
] = FX_PixelToG
[pixel
];
486 rgba
[i
][BCOMP
] = FX_PixelToB
[pixel
];
487 rgba
[i
][ACOMP
] = 255;
490 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
497 /************************************************************************/
498 /***** Depth functions *****/
499 /************************************************************************/
501 void fxDDWriteDepthSpan(GLcontext
*ctx
,
502 GLuint n
, GLint x
, GLint y
, const GLdepth depth
[],
503 const GLubyte mask
[])
505 fxMesaContext fxMesa
= (fxMesaContext
)ctx
->DriverCtx
;
506 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
508 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
509 fprintf(stderr
, "fxmesa: fxDDWriteDepthSpan(...)\n");
512 x
+= fxMesa
->x_offset
;
516 for (i
= 0; i
< n
; i
++) {
518 GLshort d
= depth
[i
];
519 writeRegionClipped(fxMesa
, GR_BUFFER_AUXBUFFER
, x
+ i
, bottom
- y
,
520 GR_LFB_SRC_FMT_ZA16
, 1, 1, 0, (void *) &d
);
525 GLushort depth16
[MAX_WIDTH
];
527 for (i
= 0; i
< n
; i
++) {
528 depth16
[i
] = depth
[i
];
530 writeRegionClipped(fxMesa
, GR_BUFFER_AUXBUFFER
, x
, bottom
- y
,
531 GR_LFB_SRC_FMT_ZA16
, n
, 1, 0, (void *) depth16
);
536 void fxDDReadDepthSpan(GLcontext
*ctx
,
537 GLuint n
, GLint x
, GLint y
, GLdepth depth
[])
539 fxMesaContext fxMesa
= (fxMesaContext
)ctx
->DriverCtx
;
540 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
541 GLushort depth16
[MAX_WIDTH
];
544 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
545 fprintf(stderr
, "fxmesa: fxDDReadDepthSpan(...)\n");
548 x
+= fxMesa
->x_offset
;
549 FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER
, x
, bottom
- y
, n
, 1, 0, depth16
);
550 for (i
= 0; i
< n
; i
++) {
551 depth
[i
] = depth16
[i
];
557 void fxDDWriteDepthPixels(GLcontext
*ctx
,
558 GLuint n
, const GLint x
[], const GLint y
[],
559 const GLdepth depth
[], const GLubyte mask
[])
561 fxMesaContext fxMesa
= (fxMesaContext
)ctx
->DriverCtx
;
562 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
565 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
566 fprintf(stderr
, "fxmesa: fxDDWriteDepthPixels(...)\n");
569 for (i
= 0; i
< n
; i
++) {
571 int xpos
= x
[i
] + fxMesa
->x_offset
;
572 int ypos
= bottom
- y
[i
];
573 GLushort d
= depth
[i
];
574 writeRegionClipped(fxMesa
, GR_BUFFER_AUXBUFFER
, xpos
, ypos
,
575 GR_LFB_SRC_FMT_ZA16
, 1, 1, 0, (void *) &d
);
581 void fxDDReadDepthPixels(GLcontext
*ctx
, GLuint n
,
582 const GLint x
[], const GLint y
[], GLdepth depth
[])
584 fxMesaContext fxMesa
= (fxMesaContext
)ctx
->DriverCtx
;
585 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
588 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
589 fprintf(stderr
, "fxmesa: fxDDReadDepthPixels(...)\n");
592 for (i
= 0; i
< n
; i
++) {
593 int xpos
= x
[i
] + fxMesa
->x_offset
;
594 int ypos
= bottom
- y
[i
];
596 FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER
, xpos
, ypos
, 1, 1, 0, &d
);
604 /************************************************************************/
607 void fxSetupDDSpanPointers(GLcontext
*ctx
)
609 ctx
->Driver
.WriteRGBASpan
=fxDDWriteRGBASpan
;
610 ctx
->Driver
.WriteRGBSpan
=fxDDWriteRGBSpan
;
611 ctx
->Driver
.WriteMonoRGBASpan
=fxDDWriteMonoRGBASpan
;
612 ctx
->Driver
.WriteRGBAPixels
=fxDDWriteRGBAPixels
;
613 ctx
->Driver
.WriteMonoRGBAPixels
=fxDDWriteMonoRGBAPixels
;
615 ctx
->Driver
.WriteCI8Span
=NULL
;
616 ctx
->Driver
.WriteCI32Span
=NULL
;
617 ctx
->Driver
.WriteMonoCISpan
=NULL
;
618 ctx
->Driver
.WriteCI32Pixels
=NULL
;
619 ctx
->Driver
.WriteMonoCIPixels
=NULL
;
621 /* ctx->Driver.ReadRGBASpan =fxDDReadRGBASpan;*/
622 ctx
->Driver
.ReadRGBASpan
= read_R5G6B5_span
;
623 ctx
->Driver
.ReadRGBAPixels
= read_R5G6B5_pixels
;
625 ctx
->Driver
.ReadCI32Span
=NULL
;
626 ctx
->Driver
.ReadCI32Pixels
=NULL
;
634 * Need this to provide at least one external definition.
637 int gl_fx_dummy_function_span(void)