3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
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:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
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.
26 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
29 * Thank you for your contribution, David!
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.
37 * Additional Mesa/3Dfx driver developers:
38 * Daryll Strauss <daryll@precisioninsight.com>
39 * Keith Whitwell <keith@precisioninsight.com>
41 * See fxapi.h for more revision/author details.
45 /* fxdd.c - 3Dfx VooDoo Mesa span and pixel functions */
55 #include "swrast/swrast.h"
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)
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)
76 /* KW: Rearranged the args in the call to grLfbWriteRegion().
78 #define LFB_WRITE_SPAN_MESA(dst_buffer, \
84 writeRegionClipped(fxMesa, dst_buffer, \
87 GR_LFB_SRC_FMT_8888, \
94 #else /* !defined(FXMESA_USE_RGBA) */
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)
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])) )
107 LFB_WRITE_SPAN_MESA(GrBuffer_t dst_buffer
,
110 FxU32 src_width
, FxI32 src_stride
, void *src_data
)
113 GLubyte(*rgba
)[4] = src_data
;
114 GLuint argb
[MAX_WIDTH
];
117 for (i
= 0; i
< src_width
; i
++) {
118 argb
[i
] = MESACOLOR_TO_ARGB(rgba
[i
]);
120 writeRegionClipped( /*fxMesa, */ NULL
, dst_buffer
,
124 src_width
, 1, src_stride
, (void *) argb
);
127 #endif /* !defined(FXMESA_USE_RGBA) */
130 /************************************************************************/
131 /***** Span functions *****/
132 /************************************************************************/
136 fxDDWriteRGBASpan(const GLcontext
* ctx
,
137 GLuint n
, GLint x
, GLint y
,
138 const GLubyte rgba
[][4], const GLubyte mask
[])
140 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
142 GLint bottom
= fxMesa
->height
- 1;
144 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
145 fprintf(stderr
, "fxmesa: fxDDWriteRGBASpan(...)\n");
151 for (i
= 0; i
< n
; i
++) {
157 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
+ i
- span
,
159 /* GR_LFB_SRC_FMT_8888, */ span
, /*1, */ 0,
160 (void *) rgba
[i
- span
]);
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
]);
172 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
, bottom
- y
, /* GR_LFB_SRC_FMT_8888, */
173 n
, /* 1, */ 0, (void *) rgba
);
178 fxDDWriteRGBSpan(const GLcontext
* ctx
,
179 GLuint n
, GLint x
, GLint y
,
180 const GLubyte rgb
[][3], const GLubyte mask
[])
182 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
184 GLint bottom
= fxMesa
->height
- 1;
185 GLubyte rgba
[MAX_WIDTH
][4];
187 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
188 fprintf(stderr
, "fxmesa: fxDDWriteRGBSpan()\n");
194 for (i
= 0; i
< n
; 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;
204 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
+ i
- span
,
206 /*GR_LFB_SRC_FMT_8888, */ span
, /* 1, */ 0,
214 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
+ n
- span
, bottom
- y
,
215 /*GR_LFB_SRC_FMT_8888, */ span
, /* 1, */ 0,
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;
226 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
, bottom
- y
, /* GR_LFB_SRC_FMT_8888, */
227 n
, /* 1, */ 0, (void *) rgba
);
233 fxDDWriteMonoRGBASpan(const GLcontext
* ctx
,
234 GLuint n
, GLint x
, GLint y
,
235 const GLchan color
[4], const GLubyte mask
[])
237 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
239 GLint bottom
= fxMesa
->height
- 1;
240 GLuint data
[MAX_WIDTH
];
241 GrColor_t gColor
= FXCOLOR4(color
);
243 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
244 fprintf(stderr
, "fxmesa: fxDDWriteMonoRGBASpan(...)\n");
250 for (i
= 0; i
< n
; i
++) {
252 data
[span
] = (GLuint
) gColor
;
257 writeRegionClipped(fxMesa
, fxMesa
->currentFB
, x
+ i
- span
,
258 bottom
- y
, GR_LFB_SRC_FMT_8888
, span
, 1, 0,
266 writeRegionClipped(fxMesa
, fxMesa
->currentFB
, x
+ n
- span
,
267 bottom
- y
, GR_LFB_SRC_FMT_8888
, span
, 1, 0,
271 for (i
= 0; i
< n
; i
++) {
272 data
[i
] = (GLuint
) gColor
;
275 writeRegionClipped(fxMesa
, fxMesa
->currentFB
, x
, bottom
- y
,
276 GR_LFB_SRC_FMT_8888
, n
, 1, 0, (void *) data
);
283 fxDDReadRGBASpan(const GLcontext
* ctx
,
284 GLuint n
, GLint x
, GLint y
, GLubyte rgba
[][4])
286 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
287 GLushort data
[MAX_WIDTH
];
289 GLint bottom
= fxMesa
->height
- 1;
291 printf("read span %d, %d, %d\n", x
, y
, n
);
292 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
293 fprintf(stderr
, "fxmesa: fxDDReadRGBASpan(...)\n");
296 assert(n
< MAX_WIDTH
);
298 FX_grLfbReadRegion(fxMesa
->currentFB
, x
, bottom
- y
, n
, 1, 0, data
);
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;
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.
316 read_R5G6B5_span(const GLcontext
* ctx
,
317 GLuint n
, GLint x
, GLint y
, GLubyte rgba
[][4])
319 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
322 if (grLfbLock(GR_LFB_READ_ONLY
,
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
;
332 GLuint extraPixel
= (n
& 1);
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;
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;
355 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
361 /************************************************************************/
362 /***** Pixel functions *****/
363 /************************************************************************/
366 fxDDWriteRGBAPixels(const GLcontext
* ctx
,
367 GLuint n
, const GLint x
[], const GLint y
[],
368 CONST GLubyte rgba
[][4], const GLubyte mask
[])
370 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
372 GLint bottom
= fxMesa
->height
- 1;
374 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
375 fprintf(stderr
, "fxmesa: fxDDWriteRGBAPixels(...)\n");
378 for (i
= 0; i
< n
; i
++)
380 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
[i
], bottom
- y
[i
],
381 1, 1, (void *) rgba
[i
]);
385 fxDDWriteMonoRGBAPixels(const GLcontext
* ctx
,
386 GLuint n
, const GLint x
[], const GLint y
[],
387 const GLchan color
[4], const GLubyte mask
[])
389 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
391 GLint bottom
= fxMesa
->height
- 1;
392 GrColor_t gColor
= FXCOLOR4(color
);
394 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
395 fprintf(stderr
, "fxmesa: fxDDWriteMonoRGBAPixels(...)\n");
398 for (i
= 0; i
< n
; i
++)
400 writeRegionClipped(fxMesa
, fxMesa
->currentFB
, x
[i
], bottom
- y
[i
],
401 GR_LFB_SRC_FMT_8888
, 1, 1, 0, (void *) &gColor
);
406 read_R5G6B5_pixels(const GLcontext
* ctx
,
407 GLuint n
, const GLint x
[], const GLint y
[],
408 GLubyte rgba
[][4], const GLubyte mask
[])
410 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
413 if (grLfbLock(GR_LFB_READ_ONLY
,
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;
420 for (i
= 0; i
< n
; 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;
431 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
438 /************************************************************************/
439 /***** Depth functions *****/
440 /************************************************************************/
443 fxDDWriteDepthSpan(GLcontext
* ctx
,
444 GLuint n
, GLint x
, GLint y
, const GLdepth depth
[],
445 const GLubyte mask
[])
447 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
448 GLint bottom
= fxMesa
->height
- 1;
450 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
451 fprintf(stderr
, "fxmesa: fxDDWriteDepthSpan(...)\n");
457 for (i
= 0; i
< n
; 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
);
466 GLushort depth16
[MAX_WIDTH
];
468 for (i
= 0; i
< n
; i
++) {
469 depth16
[i
] = depth
[i
];
471 writeRegionClipped(fxMesa
, GR_BUFFER_AUXBUFFER
, x
, bottom
- y
,
472 GR_LFB_SRC_FMT_ZA16
, n
, 1, 0, (void *) depth16
);
478 fxDDReadDepthSpan(GLcontext
* ctx
,
479 GLuint n
, GLint x
, GLint y
, GLdepth depth
[])
481 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
482 GLint bottom
= fxMesa
->height
- 1;
483 GLushort depth16
[MAX_WIDTH
];
486 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
487 fprintf(stderr
, "fxmesa: fxDDReadDepthSpan(...)\n");
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
];
499 fxDDWriteDepthPixels(GLcontext
* ctx
,
500 GLuint n
, const GLint x
[], const GLint y
[],
501 const GLdepth depth
[], const GLubyte mask
[])
503 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
504 GLint bottom
= fxMesa
->height
- 1;
507 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
508 fprintf(stderr
, "fxmesa: fxDDWriteDepthPixels(...)\n");
511 for (i
= 0; i
< n
; 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
);
524 fxDDReadDepthPixels(GLcontext
* ctx
, GLuint n
,
525 const GLint x
[], const GLint y
[], GLdepth depth
[])
527 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
528 GLint bottom
= fxMesa
->height
- 1;
531 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
532 fprintf(stderr
, "fxmesa: fxDDReadDepthPixels(...)\n");
535 for (i
= 0; i
< n
; i
++) {
537 int ypos
= bottom
- y
[i
];
539 FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER
, xpos
, ypos
, 1, 1, 0, &d
);
546 /* Set the buffer used for reading */
547 /* XXX support for separate read/draw buffers hasn't been tested */
549 fxDDSetReadBuffer(GLcontext
* ctx
, GLframebuffer
* buffer
, GLenum mode
)
551 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
554 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
555 fprintf(stderr
, "fxmesa: fxDDSetBuffer(%x)\n", (int) mode
);
558 if (mode
== GL_FRONT_LEFT
) {
559 fxMesa
->currentFB
= GR_BUFFER_FRONTBUFFER
;
560 FX_grRenderBuffer(fxMesa
->currentFB
);
562 else if (mode
== GL_BACK_LEFT
) {
563 fxMesa
->currentFB
= GR_BUFFER_BACKBUFFER
;
564 FX_grRenderBuffer(fxMesa
->currentFB
);
569 /************************************************************************/
574 fxSetupDDSpanPointers(GLcontext
* ctx
)
576 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
578 swdd
->SetReadBuffer
= fxDDSetReadBuffer
;
580 swdd
->WriteRGBASpan
= fxDDWriteRGBASpan
;
581 swdd
->WriteRGBSpan
= fxDDWriteRGBSpan
;
582 swdd
->WriteMonoRGBASpan
= fxDDWriteMonoRGBASpan
;
583 swdd
->WriteRGBAPixels
= fxDDWriteRGBAPixels
;
584 swdd
->WriteMonoRGBAPixels
= fxDDWriteMonoRGBAPixels
;
586 swdd
->WriteDepthSpan
= fxDDWriteDepthSpan
;
587 swdd
->WriteDepthPixels
= fxDDWriteDepthPixels
;
588 swdd
->ReadDepthSpan
= fxDDReadDepthSpan
;
589 swdd
->ReadDepthPixels
= fxDDReadDepthPixels
;
591 /* swdd->ReadRGBASpan =fxDDReadRGBASpan; */
592 swdd
->ReadRGBASpan
= read_R5G6B5_span
;
593 swdd
->ReadRGBAPixels
= read_R5G6B5_pixels
;
601 * Need this to provide at least one external definition.
604 extern int gl_fx_dummy_function_span(void);
606 gl_fx_dummy_function_span(void)