1 /* $Id: fxddspan.c,v 1.19 2001/09/23 16:50:01 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 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.
35 /* fxdd.c - 3Dfx VooDoo Mesa span and pixel functions */
45 #include "swrast/swrast.h"
49 #pragma warning( disable : 4090 4022 )
50 /* 4101 : "different 'const' qualifier"
51 * 4022 : "pointer mistmatch for actual parameter 'n'
57 #if !defined(FXMESA_USE_ARGB)
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)
66 /* KW: Rearranged the args in the call to grLfbWriteRegion().
68 #define LFB_WRITE_SPAN_MESA(dst_buffer, \
74 writeRegionClipped(fxMesa, dst_buffer, \
77 GR_LFB_SRC_FMT_8888, \
84 #else /* !defined(FXMESA_USE_RGBA) */
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)
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])) )
97 LFB_WRITE_SPAN_MESA(GrBuffer_t dst_buffer
,
100 FxU32 src_width
, FxI32 src_stride
, void *src_data
)
103 GLubyte(*rgba
)[4] = src_data
;
104 GLuint argb
[MAX_WIDTH
];
107 for (i
= 0; i
< src_width
; i
++) {
108 argb
[i
] = MESACOLOR_TO_ARGB(rgba
[i
]);
110 writeRegionClipped( /*fxMesa, */ NULL
, dst_buffer
,
114 src_width
, 1, src_stride
, (void *) argb
);
117 #endif /* !defined(FXMESA_USE_RGBA) */
120 /************************************************************************/
121 /***** Span functions *****/
122 /************************************************************************/
126 fxDDWriteRGBASpan(const GLcontext
* ctx
,
127 GLuint n
, GLint x
, GLint y
,
128 const GLubyte rgba
[][4], const GLubyte mask
[])
130 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
132 GLint bottom
= fxMesa
->height
- 1;
134 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
135 fprintf(stderr
, "fxmesa: fxDDWriteRGBASpan(...)\n");
141 for (i
= 0; i
< n
; i
++) {
147 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
+ i
- span
,
149 /* GR_LFB_SRC_FMT_8888, */ span
, /*1, */ 0,
150 (void *) rgba
[i
- span
]);
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
]);
162 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
, bottom
- y
, /* GR_LFB_SRC_FMT_8888, */
163 n
, /* 1, */ 0, (void *) rgba
);
168 fxDDWriteRGBSpan(const GLcontext
* ctx
,
169 GLuint n
, GLint x
, GLint y
,
170 const GLubyte rgb
[][3], const GLubyte mask
[])
172 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
174 GLint bottom
= fxMesa
->height
- 1;
175 GLubyte rgba
[MAX_WIDTH
][4];
177 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
178 fprintf(stderr
, "fxmesa: fxDDWriteRGBSpan()\n");
184 for (i
= 0; i
< n
; 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;
194 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
+ i
- span
,
196 /*GR_LFB_SRC_FMT_8888, */ span
, /* 1, */ 0,
204 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
+ n
- span
, bottom
- y
,
205 /*GR_LFB_SRC_FMT_8888, */ span
, /* 1, */ 0,
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;
216 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
, bottom
- y
, /* GR_LFB_SRC_FMT_8888, */
217 n
, /* 1, */ 0, (void *) rgba
);
223 fxDDWriteMonoRGBASpan(const GLcontext
* ctx
,
224 GLuint n
, GLint x
, GLint y
,
225 const GLchan color
[4], const GLubyte mask
[])
227 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
229 GLint bottom
= fxMesa
->height
- 1;
230 GLuint data
[MAX_WIDTH
];
231 GrColor_t gColor
= FXCOLOR4(color
);
233 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
234 fprintf(stderr
, "fxmesa: fxDDWriteMonoRGBASpan(...)\n");
240 for (i
= 0; i
< n
; i
++) {
242 data
[span
] = (GLuint
) gColor
;
247 writeRegionClipped(fxMesa
, fxMesa
->currentFB
, x
+ i
- span
,
248 bottom
- y
, GR_LFB_SRC_FMT_8888
, span
, 1, 0,
256 writeRegionClipped(fxMesa
, fxMesa
->currentFB
, x
+ n
- span
,
257 bottom
- y
, GR_LFB_SRC_FMT_8888
, span
, 1, 0,
261 for (i
= 0; i
< n
; i
++) {
262 data
[i
] = (GLuint
) gColor
;
265 writeRegionClipped(fxMesa
, fxMesa
->currentFB
, x
, bottom
- y
,
266 GR_LFB_SRC_FMT_8888
, n
, 1, 0, (void *) data
);
273 fxDDReadRGBASpan(const GLcontext
* ctx
,
274 GLuint n
, GLint x
, GLint y
, GLubyte rgba
[][4])
276 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
277 GLushort data
[MAX_WIDTH
];
279 GLint bottom
= fxMesa
->height
- 1;
281 printf("read span %d, %d, %d\n", x
, y
, n
);
282 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
283 fprintf(stderr
, "fxmesa: fxDDReadRGBASpan(...)\n");
286 assert(n
< MAX_WIDTH
);
288 FX_grLfbReadRegion(fxMesa
->currentFB
, x
, bottom
- y
, n
, 1, 0, data
);
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;
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.
306 read_R5G6B5_span(const GLcontext
* ctx
,
307 GLuint n
, GLint x
, GLint y
, GLubyte rgba
[][4])
309 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
312 if (grLfbLock(GR_LFB_READ_ONLY
,
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
;
322 GLuint extraPixel
= (n
& 1);
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;
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;
345 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
351 /************************************************************************/
352 /***** Pixel functions *****/
353 /************************************************************************/
356 fxDDWriteRGBAPixels(const GLcontext
* ctx
,
357 GLuint n
, const GLint x
[], const GLint y
[],
358 CONST GLubyte rgba
[][4], const GLubyte mask
[])
360 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
362 GLint bottom
= fxMesa
->height
- 1;
364 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
365 fprintf(stderr
, "fxmesa: fxDDWriteRGBAPixels(...)\n");
368 for (i
= 0; i
< n
; i
++)
370 LFB_WRITE_SPAN_MESA(fxMesa
->currentFB
, x
[i
], bottom
- y
[i
],
371 1, 1, (void *) rgba
[i
]);
375 fxDDWriteMonoRGBAPixels(const GLcontext
* ctx
,
376 GLuint n
, const GLint x
[], const GLint y
[],
377 const GLchan color
[4], const GLubyte mask
[])
379 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
381 GLint bottom
= fxMesa
->height
- 1;
382 GrColor_t gColor
= FXCOLOR4(color
);
384 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
385 fprintf(stderr
, "fxmesa: fxDDWriteMonoRGBAPixels(...)\n");
388 for (i
= 0; i
< n
; i
++)
390 writeRegionClipped(fxMesa
, fxMesa
->currentFB
, x
[i
], bottom
- y
[i
],
391 GR_LFB_SRC_FMT_8888
, 1, 1, 0, (void *) &gColor
);
396 read_R5G6B5_pixels(const GLcontext
* ctx
,
397 GLuint n
, const GLint x
[], const GLint y
[],
398 GLubyte rgba
[][4], const GLubyte mask
[])
400 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
403 if (grLfbLock(GR_LFB_READ_ONLY
,
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;
410 for (i
= 0; i
< n
; 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;
421 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
428 /************************************************************************/
429 /***** Depth functions *****/
430 /************************************************************************/
433 fxDDWriteDepthSpan(GLcontext
* ctx
,
434 GLuint n
, GLint x
, GLint y
, const GLdepth depth
[],
435 const GLubyte mask
[])
437 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
438 GLint bottom
= fxMesa
->height
- 1;
440 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
441 fprintf(stderr
, "fxmesa: fxDDWriteDepthSpan(...)\n");
447 for (i
= 0; i
< n
; 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
);
456 GLushort depth16
[MAX_WIDTH
];
458 for (i
= 0; i
< n
; i
++) {
459 depth16
[i
] = depth
[i
];
461 writeRegionClipped(fxMesa
, GR_BUFFER_AUXBUFFER
, x
, bottom
- y
,
462 GR_LFB_SRC_FMT_ZA16
, n
, 1, 0, (void *) depth16
);
468 fxDDReadDepthSpan(GLcontext
* ctx
,
469 GLuint n
, GLint x
, GLint y
, GLdepth depth
[])
471 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
472 GLint bottom
= fxMesa
->height
- 1;
473 GLushort depth16
[MAX_WIDTH
];
476 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
477 fprintf(stderr
, "fxmesa: fxDDReadDepthSpan(...)\n");
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
];
489 fxDDWriteDepthPixels(GLcontext
* ctx
,
490 GLuint n
, const GLint x
[], const GLint y
[],
491 const GLdepth depth
[], const GLubyte mask
[])
493 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
494 GLint bottom
= fxMesa
->height
- 1;
497 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
498 fprintf(stderr
, "fxmesa: fxDDWriteDepthPixels(...)\n");
501 for (i
= 0; i
< n
; 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
);
514 fxDDReadDepthPixels(GLcontext
* ctx
, GLuint n
,
515 const GLint x
[], const GLint y
[], GLdepth depth
[])
517 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
518 GLint bottom
= fxMesa
->height
- 1;
521 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
522 fprintf(stderr
, "fxmesa: fxDDReadDepthPixels(...)\n");
525 for (i
= 0; i
< n
; i
++) {
527 int ypos
= bottom
- y
[i
];
529 FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER
, xpos
, ypos
, 1, 1, 0, &d
);
536 /* Set the buffer used for reading */
537 /* XXX support for separate read/draw buffers hasn't been tested */
539 fxDDSetReadBuffer(GLcontext
* ctx
, GLframebuffer
* buffer
, GLenum mode
)
541 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
544 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
545 fprintf(stderr
, "fxmesa: fxDDSetBuffer(%x)\n", (int) mode
);
548 if (mode
== GL_FRONT_LEFT
) {
549 fxMesa
->currentFB
= GR_BUFFER_FRONTBUFFER
;
550 FX_grRenderBuffer(fxMesa
->currentFB
);
552 else if (mode
== GL_BACK_LEFT
) {
553 fxMesa
->currentFB
= GR_BUFFER_BACKBUFFER
;
554 FX_grRenderBuffer(fxMesa
->currentFB
);
559 /************************************************************************/
564 fxSetupDDSpanPointers(GLcontext
* ctx
)
566 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
568 swdd
->SetReadBuffer
= fxDDSetReadBuffer
;
570 swdd
->WriteRGBASpan
= fxDDWriteRGBASpan
;
571 swdd
->WriteRGBSpan
= fxDDWriteRGBSpan
;
572 swdd
->WriteMonoRGBASpan
= fxDDWriteMonoRGBASpan
;
573 swdd
->WriteRGBAPixels
= fxDDWriteRGBAPixels
;
574 swdd
->WriteMonoRGBAPixels
= fxDDWriteMonoRGBAPixels
;
576 swdd
->WriteDepthSpan
= fxDDWriteDepthSpan
;
577 swdd
->WriteDepthPixels
= fxDDWriteDepthPixels
;
578 swdd
->ReadDepthSpan
= fxDDReadDepthSpan
;
579 swdd
->ReadDepthPixels
= fxDDReadDepthPixels
;
581 /* swdd->ReadRGBASpan =fxDDReadRGBASpan; */
582 swdd
->ReadRGBASpan
= read_R5G6B5_span
;
583 swdd
->ReadRGBAPixels
= read_R5G6B5_pixels
;
591 * Need this to provide at least one external definition.
594 extern int gl_fx_dummy_function_span(void);
596 gl_fx_dummy_function_span(void)