2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 /* fxdd.c - 3Dfx VooDoo Mesa device driver functions */
47 #include "extensions.h"
51 #include "swrast/swrast.h"
52 #include "swrast/s_context.h"
53 #include "swrast_setup/swrast_setup.h"
55 #include "tnl/t_context.h"
56 #include "tnl/t_pipeline.h"
57 #include "array_cache/acache.h"
61 /* lookup table for scaling 4 bit colors up to 8 bits */
62 GLuint FX_rgb_scale_4
[16] = {
63 0, 17, 34, 51, 68, 85, 102, 119,
64 136, 153, 170, 187, 204, 221, 238, 255
67 /* lookup table for scaling 5 bit colors up to 8 bits */
68 GLuint FX_rgb_scale_5
[32] = {
69 0, 8, 16, 25, 33, 41, 49, 58,
70 66, 74, 82, 90, 99, 107, 115, 123,
71 132, 140, 148, 156, 165, 173, 181, 189,
72 197, 206, 214, 222, 230, 239, 247, 255
75 /* lookup table for scaling 6 bit colors up to 8 bits */
76 GLuint FX_rgb_scale_6
[64] = {
77 0, 4, 8, 12, 16, 20, 24, 28,
78 32, 36, 40, 45, 49, 53, 57, 61,
79 65, 69, 73, 77, 81, 85, 89, 93,
80 97, 101, 105, 109, 113, 117, 121, 125,
81 130, 134, 138, 142, 146, 150, 154, 158,
82 162, 166, 170, 174, 178, 182, 186, 190,
83 194, 198, 202, 206, 210, 215, 219, 223,
84 227, 231, 235, 239, 243, 247, 251, 255
89 * Disable color by masking out R, G, B, A
91 static void fxDisableColor (fxMesaContext fxMesa
)
93 if (fxMesa
->colDepth
== 32) {
95 fxMesa
->Glide
.grColorMaskExt(FXFALSE
, FXFALSE
, FXFALSE
, FXFALSE
);
98 grColorMask(FXFALSE
, FXFALSE
);
103 /**********************************************************************/
104 /***** Miscellaneous functions *****/
105 /**********************************************************************/
107 /* Return buffer size information */
109 fxDDBufferSize(GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
111 GET_CURRENT_CONTEXT(ctx
);
112 if (ctx
&& FX_CONTEXT(ctx
)) {
113 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
115 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
116 fprintf(stderr
, "fxDDBufferSize(...)\n");
119 *width
= fxMesa
->width
;
120 *height
= fxMesa
->height
;
125 /* Implements glClearColor() */
127 fxDDClearColor(GLcontext
* ctx
, const GLfloat color
[4])
129 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
132 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
133 fprintf(stderr
, "fxDDClearColor(%f, %f, %f, %f)\n",
134 color
[0], color
[1], color
[2], color
[3]);
137 CLAMPED_FLOAT_TO_UBYTE(col
[0], color
[0]);
138 CLAMPED_FLOAT_TO_UBYTE(col
[1], color
[1]);
139 CLAMPED_FLOAT_TO_UBYTE(col
[2], color
[2]);
140 CLAMPED_FLOAT_TO_UBYTE(col
[3], color
[3]);
142 fxMesa
->clearC
= FXCOLOR4(col
);
143 fxMesa
->clearA
= col
[3];
147 /* Clear the color and/or depth buffers */
148 static void fxDDClear( GLcontext
*ctx
,
149 GLbitfield mask
, GLboolean all
,
150 GLint x
, GLint y
, GLint width
, GLint height
)
152 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
153 GLbitfield softwareMask
= mask
& (DD_ACCUM_BIT
);
154 const GLuint stencil_size
= fxMesa
->haveHwStencil
? ctx
->Visual
.stencilBits
: 0;
155 const FxU32 clearD
= (FxU32
) (ctx
->DepthMaxF
* ctx
->Depth
.Clear
);
156 const FxU8 clearS
= (FxU8
) (ctx
->Stencil
.Clear
& 0xff);
158 if ( TDFX_DEBUG
& MESA_VERBOSE
) {
159 fprintf( stderr
, "fxDDClear( %d, %d, %d, %d )\n",
160 (int) x
, (int) y
, (int) width
, (int) height
);
163 /* Need this check to respond to glScissor and clipping updates */
164 /* should also take care of FX_NEW_COLOR_MASK, FX_NEW_STENCIL, depth? */
165 if (fxMesa
->new_state
& FX_NEW_SCISSOR
) {
167 fxMesa
->new_state
&= ~FX_NEW_SCISSOR
;
170 /* we can't clear accum buffers */
171 mask
&= ~(DD_ACCUM_BIT
);
174 * As per GL spec, stencil masking should be obeyed when clearing
176 if (mask
& DD_STENCIL_BIT
) {
177 if (!fxMesa
->haveHwStencil
|| fxMesa
->unitsState
.stencilWriteMask
!= 0xff) {
178 /* Napalm seems to have trouble with stencil write masks != 0xff */
179 /* do stencil clear in software */
180 softwareMask
|= DD_STENCIL_BIT
;
181 mask
&= ~(DD_STENCIL_BIT
);
186 * As per GL spec, color masking should be obeyed when clearing
188 if (ctx
->Visual
.greenBits
!= 8) {
189 /* can only do color masking if running in 24/32bpp on Napalm */
190 if (ctx
->Color
.ColorMask
[RCOMP
] != ctx
->Color
.ColorMask
[GCOMP
] ||
191 ctx
->Color
.ColorMask
[GCOMP
] != ctx
->Color
.ColorMask
[BCOMP
]) {
192 softwareMask
|= (mask
& (DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
));
193 mask
&= ~(DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
);
197 if (fxMesa
->haveHwStencil
) {
199 * If we want to clear stencil, it must be enabled
200 * in the HW, even if the stencil test is not enabled
204 if (mask
& DD_STENCIL_BIT
) {
205 fxMesa
->Glide
.grStencilMaskExt(0xff /*fxMesa->unitsState.stencilWriteMask*/);
206 /* set stencil ref value = desired clear value */
207 fxMesa
->Glide
.grStencilFuncExt(GR_CMP_ALWAYS
, clearS
, 0xff);
208 fxMesa
->Glide
.grStencilOpExt(GR_STENCILOP_REPLACE
,
209 GR_STENCILOP_REPLACE
, GR_STENCILOP_REPLACE
);
210 grEnable(GR_STENCIL_MODE_EXT
);
213 grDisable(GR_STENCIL_MODE_EXT
);
219 * This may be ugly, but it's needed in order to work around a number
225 * This could probably be done fancier but doing each possible case
226 * explicitly is less error prone.
228 switch (mask
& ~DD_STENCIL_BIT
) {
229 case DD_BACK_LEFT_BIT
| DD_DEPTH_BIT
:
230 /* back buffer & depth */
231 /* FX_grColorMaskv_NoLock(ctx, true4); */ /* work around Voodoo3 bug */
233 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
234 if (stencil_size
> 0) {
235 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
240 grBufferClear(fxMesa
->clearC
,
243 if (!fxMesa
->unitsState
.depthTestEnabled
) {
244 grDepthMask(FXFALSE
);
247 case DD_FRONT_LEFT_BIT
| DD_DEPTH_BIT
:
248 /* XXX it appears that the depth buffer isn't cleared when
249 * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
250 * This is a work-around/
254 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
255 fxDisableColor(fxMesa
);
256 if (stencil_size
> 0)
257 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
261 grBufferClear(fxMesa
->clearC
,
265 fxSetupColorMask(ctx
);
266 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
267 if (stencil_size
> 0)
268 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
272 grBufferClear(fxMesa
->clearC
,
275 if (!fxMesa
->unitsState
.depthTestEnabled
) {
276 grDepthMask(FXFALSE
);
279 case DD_BACK_LEFT_BIT
:
280 /* back buffer only */
281 grDepthMask(FXFALSE
);
282 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
283 if (stencil_size
> 0)
284 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
288 grBufferClear(fxMesa
->clearC
,
291 if (fxMesa
->unitsState
.depthTestEnabled
) {
295 case DD_FRONT_LEFT_BIT
:
296 /* front buffer only */
297 grDepthMask(FXFALSE
);
298 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
299 if (stencil_size
> 0)
300 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
304 grBufferClear(fxMesa
->clearC
,
307 if (fxMesa
->unitsState
.depthTestEnabled
) {
311 case DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
:
313 grDepthMask(FXFALSE
);
314 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
315 if (stencil_size
> 0)
316 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
320 grBufferClear(fxMesa
->clearC
,
323 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
324 if (stencil_size
> 0)
325 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
329 grBufferClear(fxMesa
->clearC
,
332 if (fxMesa
->unitsState
.depthTestEnabled
) {
336 case DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
| DD_DEPTH_BIT
:
338 grDepthMask(FXFALSE
);
339 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
340 if (stencil_size
> 0)
341 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
345 grBufferClear(fxMesa
->clearC
,
348 /* clear back and depth */
350 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
351 if (stencil_size
> 0)
352 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
356 grBufferClear(fxMesa
->clearC
,
359 if (!fxMesa
->unitsState
.depthTestEnabled
) {
360 grDepthMask(FXFALSE
);
364 /* just the depth buffer */
365 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
366 fxDisableColor(fxMesa
);
368 if (stencil_size
> 0)
369 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
373 grBufferClear(fxMesa
->clearC
,
376 fxSetupColorMask(ctx
);
377 if (ctx
->Color
._DrawDestMask
& DD_FRONT_LEFT_BIT
) {
378 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
380 if (!fxMesa
->unitsState
.depthTestEnabled
) {
381 grDepthMask(FXFALSE
);
385 /* clear no color buffers or depth buffer but might clear stencil */
386 if (stencil_size
> 0 && (mask
& DD_STENCIL_BIT
)) {
387 /* XXX need this RenderBuffer call to work around Glide bug */
388 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
389 grDepthMask(FXFALSE
);
390 fxDisableColor(fxMesa
);
391 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
394 if (fxMesa
->unitsState
.depthTestEnabled
) {
397 fxSetupColorMask(ctx
);
398 if (ctx
->Color
._DrawDestMask
& DD_FRONT_LEFT_BIT
) {
399 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
406 if (fxMesa
->haveHwStencil
&& (mask
& DD_STENCIL_BIT
)) {
407 /* We changed the stencil state above. Signal that we need to
410 fxMesa
->new_state
|= FX_NEW_STENCIL
;
414 _swrast_Clear( ctx
, softwareMask
, all
, x
, y
, width
, height
);
418 /* Set the buffer used for drawing */
419 /* XXX support for separate read/draw buffers hasn't been tested */
421 fxDDSetDrawBuffer(GLcontext
* ctx
, GLenum mode
)
423 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
425 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
426 fprintf(stderr
, "fxDDSetDrawBuffer(%x)\n", (int)mode
);
429 if (mode
== GL_FRONT_LEFT
) {
430 fxMesa
->currentFB
= GR_BUFFER_FRONTBUFFER
;
431 grRenderBuffer(fxMesa
->currentFB
);
433 else if (mode
== GL_BACK_LEFT
) {
434 fxMesa
->currentFB
= GR_BUFFER_BACKBUFFER
;
435 grRenderBuffer(fxMesa
->currentFB
);
437 else if (mode
== GL_NONE
) {
438 fxDisableColor(fxMesa
);
441 /* we'll need a software fallback */
442 /* XXX not implemented */
445 /* update s/w fallback state */
446 _swrast_DrawBuffer(ctx
, mode
);
451 fxDDDrawBitmap2 (GLcontext
*ctx
, GLint px
, GLint py
,
452 GLsizei width
, GLsizei height
,
453 const struct gl_pixelstore_attrib
*unpack
,
454 const GLubyte
*bitmap
)
456 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
457 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
459 GrLfbWriteMode_t mode
;
461 const struct gl_pixelstore_attrib
*finalUnpack
;
462 struct gl_pixelstore_attrib scissoredUnpack
;
464 /* check if there's any raster operations enabled which we can't handle */
465 if (swrast
->_RasterMask
& (ALPHATEST_BIT
|
466 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
467 DEPTH_BIT
| /* could be done with RGB:DEPTH */
468 FOG_BIT
| /* could be done with RGB:DEPTH */
470 /*CLIP_BIT |*/ /* clipping ok, below */
473 ALPHABUF_BIT
| /* nope! see 565 span kludge */
475 OCCLUSION_BIT
| /* nope! at least not yet */
478 _swrast_Bitmap(ctx
, px
, py
, width
, height
, unpack
, bitmap
);
482 /* make sure the pixelpipe is configured correctly */
485 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
486 if (ctx
->Scissor
.Enabled
) {
487 /* This is a bit tricky, but by carefully adjusting the px, py,
488 * width, height, skipPixels and skipRows values we can do
489 * scissoring without special code in the rendering loop.
492 /* we'll construct a new pixelstore struct */
493 finalUnpack
= &scissoredUnpack
;
494 scissoredUnpack
= *unpack
;
495 if (scissoredUnpack
.RowLength
== 0)
496 scissoredUnpack
.RowLength
= width
;
499 if (px
< ctx
->Scissor
.X
) {
500 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- px
);
501 width
-= (ctx
->Scissor
.X
- px
);
505 if (px
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
506 width
-= (px
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
509 if (py
< ctx
->Scissor
.Y
) {
510 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- py
);
511 height
-= (ctx
->Scissor
.Y
- py
);
515 if (py
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
516 height
-= (py
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
519 if (width
<= 0 || height
<= 0)
523 finalUnpack
= unpack
;
526 /* compute pixel value */
528 GLint r
= (GLint
) (ctx
->Current
.RasterColor
[RCOMP
] * 255.0f
);
529 GLint g
= (GLint
) (ctx
->Current
.RasterColor
[GCOMP
] * 255.0f
);
530 GLint b
= (GLint
) (ctx
->Current
.RasterColor
[BCOMP
] * 255.0f
);
531 GLint a
= (GLint
) (ctx
->Current
.RasterColor
[ACOMP
] * 255.0f
);
532 if (fxMesa
->colDepth
== 15) {
533 color
= TDFXPACKCOLOR1555(b
, g
, r
, a
);
534 mode
= GR_LFBWRITEMODE_1555
;
536 color
= fxMesa
->bgrOrder
? TDFXPACKCOLOR565(r
, g
, b
) : TDFXPACKCOLOR565(b
, g
, r
);
537 mode
= GR_LFBWRITEMODE_565
;
541 info
.size
= sizeof(info
);
542 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
545 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
546 _swrast_Bitmap(ctx
, px
, py
, width
, height
, finalUnpack
, bitmap
);
551 const GLint winX
= 0;
552 const GLint winY
= 0;
553 /* The dest stride depends on the hardware and whether we're drawing
554 * to the front or back buffer. This compile-time test seems to do
557 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
560 /* compute dest address of bottom-left pixel in bitmap */
561 GLushort
*dst
= (GLushort
*) info
.lfbPtr
562 + (winY
+ py
) * dstStride
+ (winX
+ px
);
564 for (row
= 0; row
< height
; row
++) {
566 (const GLubyte
*) _mesa_image_address(finalUnpack
,
567 bitmap
, width
, height
,
568 GL_COLOR_INDEX
, GL_BITMAP
,
570 if (finalUnpack
->LsbFirst
) {
571 /* least significan bit first */
572 GLubyte mask
= 1U << (finalUnpack
->SkipPixels
& 0x7);
574 for (col
= 0; col
< width
; col
++) {
590 /* most significan bit first */
591 GLubyte mask
= 128U >> (finalUnpack
->SkipPixels
& 0x7);
593 for (col
= 0; col
< width
; col
++) {
612 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
616 fxDDDrawBitmap4 (GLcontext
*ctx
, GLint px
, GLint py
,
617 GLsizei width
, GLsizei height
,
618 const struct gl_pixelstore_attrib
*unpack
,
619 const GLubyte
*bitmap
)
621 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
622 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
625 const struct gl_pixelstore_attrib
*finalUnpack
;
626 struct gl_pixelstore_attrib scissoredUnpack
;
628 /* check if there's any raster operations enabled which we can't handle */
629 if ((swrast
->_RasterMask
& (/*ALPHATEST_BIT |*/
630 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
631 DEPTH_BIT
| /* could be done with RGB:DEPTH */
632 FOG_BIT
| /* could be done with RGB:DEPTH */
634 /*CLIP_BIT |*/ /* clipping ok, below */
636 /*MASKING_BIT |*/ /* masking ok, we're in 32bpp */
637 /*ALPHABUF_BIT |*//* alpha ok, we're in 32bpp */
639 OCCLUSION_BIT
| /* nope! at least not yet */
643 _swrast_Bitmap(ctx
, px
, py
, width
, height
, unpack
, bitmap
);
647 /* make sure the pixelpipe is configured correctly */
650 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
651 if (ctx
->Scissor
.Enabled
) {
652 /* This is a bit tricky, but by carefully adjusting the px, py,
653 * width, height, skipPixels and skipRows values we can do
654 * scissoring without special code in the rendering loop.
657 /* we'll construct a new pixelstore struct */
658 finalUnpack
= &scissoredUnpack
;
659 scissoredUnpack
= *unpack
;
660 if (scissoredUnpack
.RowLength
== 0)
661 scissoredUnpack
.RowLength
= width
;
664 if (px
< ctx
->Scissor
.X
) {
665 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- px
);
666 width
-= (ctx
->Scissor
.X
- px
);
670 if (px
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
671 width
-= (px
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
674 if (py
< ctx
->Scissor
.Y
) {
675 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- py
);
676 height
-= (ctx
->Scissor
.Y
- py
);
680 if (py
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
681 height
-= (py
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
684 if (width
<= 0 || height
<= 0)
688 finalUnpack
= unpack
;
691 /* compute pixel value */
693 GLint r
= (GLint
) (ctx
->Current
.RasterColor
[RCOMP
] * 255.0f
);
694 GLint g
= (GLint
) (ctx
->Current
.RasterColor
[GCOMP
] * 255.0f
);
695 GLint b
= (GLint
) (ctx
->Current
.RasterColor
[BCOMP
] * 255.0f
);
696 GLint a
= (GLint
) (ctx
->Current
.RasterColor
[ACOMP
] * 255.0f
);
697 color
= TDFXPACKCOLOR8888(b
, g
, r
, a
);
700 info
.size
= sizeof(info
);
701 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
703 GR_LFBWRITEMODE_8888
,
704 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
705 _swrast_Bitmap(ctx
, px
, py
, width
, height
, finalUnpack
, bitmap
);
710 const GLint winX
= 0;
711 const GLint winY
= 0;
712 /* The dest stride depends on the hardware and whether we're drawing
713 * to the front or back buffer. This compile-time test seems to do
716 const GLint dstStride
= info
.strideInBytes
/ 4; /* stride in GLuints */
719 /* compute dest address of bottom-left pixel in bitmap */
720 GLuint
*dst
= (GLuint
*) info
.lfbPtr
721 + (winY
+ py
) * dstStride
+ (winX
+ px
);
723 for (row
= 0; row
< height
; row
++) {
725 (const GLubyte
*) _mesa_image_address(finalUnpack
,
726 bitmap
, width
, height
,
727 GL_COLOR_INDEX
, GL_BITMAP
,
729 if (finalUnpack
->LsbFirst
) {
730 /* least significan bit first */
731 GLubyte mask
= 1U << (finalUnpack
->SkipPixels
& 0x7);
733 for (col
= 0; col
< width
; col
++) {
749 /* most significan bit first */
750 GLubyte mask
= 128U >> (finalUnpack
->SkipPixels
& 0x7);
752 for (col
= 0; col
< width
; col
++) {
771 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
776 fxDDReadPixels565 (GLcontext
* ctx
,
778 GLsizei width
, GLsizei height
,
779 GLenum format
, GLenum type
,
780 const struct gl_pixelstore_attrib
*packing
,
783 if (ctx
->_ImageTransferState
/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) {
784 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
789 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
793 info
.size
= sizeof(info
);
794 if (grLfbLock(GR_LFB_READ_ONLY
,
797 GR_ORIGIN_UPPER_LEFT
, FXFALSE
, &info
)) {
798 const GLint winX
= 0;
799 const GLint winY
= fxMesa
->height
- 1;
800 const GLint srcStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
801 const GLushort
*src
= (const GLushort
*) info
.lfbPtr
802 + (winY
- y
) * srcStride
+ (winX
+ x
);
803 GLubyte
*dst
= (GLubyte
*) _mesa_image_address(packing
, dstImage
,
804 width
, height
, format
,
807 _mesa_image_row_stride(packing
, width
, format
, type
);
809 if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
810 /* convert 5R6G5B into 8R8G8B */
812 const GLint halfWidth
= width
>> 1;
813 const GLint extraPixel
= (width
& 1);
814 for (row
= 0; row
< height
; row
++) {
816 for (col
= 0; col
< halfWidth
; col
++) {
817 const GLuint pixel
= ((const GLuint
*) src
)[col
];
818 *d
++ = FX_rgb_scale_5
[(pixel
>> 11) & 0x1f];
819 *d
++ = FX_rgb_scale_6
[(pixel
>> 5) & 0x3f];
820 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
821 *d
++ = FX_rgb_scale_5
[(pixel
>> 27) & 0x1f];
822 *d
++ = FX_rgb_scale_6
[(pixel
>> 21) & 0x3f];
823 *d
++ = FX_rgb_scale_5
[(pixel
>> 16) & 0x1f];
826 GLushort pixel
= src
[width
- 1];
827 *d
++ = FX_rgb_scale_5
[(pixel
>> 11) & 0x1f];
828 *d
++ = FX_rgb_scale_6
[(pixel
>> 5) & 0x3f];
829 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
835 else if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
836 /* convert 5R6G5B into 8R8G8B8A */
838 const GLint halfWidth
= width
>> 1;
839 const GLint extraPixel
= (width
& 1);
840 for (row
= 0; row
< height
; row
++) {
842 for (col
= 0; col
< halfWidth
; col
++) {
843 const GLuint pixel
= ((const GLuint
*) src
)[col
];
844 *d
++ = FX_rgb_scale_5
[(pixel
>> 11) & 0x1f];
845 *d
++ = FX_rgb_scale_6
[(pixel
>> 5) & 0x3f];
846 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
848 *d
++ = FX_rgb_scale_5
[(pixel
>> 27) & 0x1f];
849 *d
++ = FX_rgb_scale_6
[(pixel
>> 21) & 0x3f];
850 *d
++ = FX_rgb_scale_5
[(pixel
>> 16) & 0x1f];
854 const GLushort pixel
= src
[width
- 1];
855 *d
++ = FX_rgb_scale_5
[(pixel
>> 11) & 0x1f];
856 *d
++ = FX_rgb_scale_6
[(pixel
>> 5) & 0x3f];
857 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
864 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
865 /* directly memcpy 5R6G5B pixels into client's buffer */
866 const GLint widthInBytes
= width
* 2;
868 for (row
= 0; row
< height
; row
++) {
869 MEMCPY(dst
, src
, widthInBytes
);
875 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
877 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
882 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
889 fxDDReadPixels555 (GLcontext
* ctx
,
891 GLsizei width
, GLsizei height
,
892 GLenum format
, GLenum type
,
893 const struct gl_pixelstore_attrib
*packing
,
896 if (ctx
->_ImageTransferState
/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) {
897 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
902 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
906 info
.size
= sizeof(info
);
907 if (grLfbLock(GR_LFB_READ_ONLY
,
910 GR_ORIGIN_UPPER_LEFT
, FXFALSE
, &info
)) {
911 const GLint winX
= 0;
912 const GLint winY
= fxMesa
->height
- 1;
913 const GLint srcStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
914 const GLushort
*src
= (const GLushort
*) info
.lfbPtr
915 + (winY
- y
) * srcStride
+ (winX
+ x
);
916 GLubyte
*dst
= (GLubyte
*) _mesa_image_address(packing
, dstImage
,
917 width
, height
, format
,
920 _mesa_image_row_stride(packing
, width
, format
, type
);
922 if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
923 /* convert 5R5G5B into 8R8G8B */
925 const GLint halfWidth
= width
>> 1;
926 const GLint extraPixel
= (width
& 1);
927 for (row
= 0; row
< height
; row
++) {
929 for (col
= 0; col
< halfWidth
; col
++) {
930 const GLuint pixel
= ((const GLuint
*) src
)[col
];
931 *d
++ = FX_rgb_scale_5
[(pixel
>> 10) & 0x1f];
932 *d
++ = FX_rgb_scale_5
[(pixel
>> 5) & 0x1f];
933 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
934 *d
++ = FX_rgb_scale_5
[(pixel
>> 26) & 0x1f];
935 *d
++ = FX_rgb_scale_5
[(pixel
>> 21) & 0x1f];
936 *d
++ = FX_rgb_scale_5
[(pixel
>> 16) & 0x1f];
939 GLushort pixel
= src
[width
- 1];
940 *d
++ = FX_rgb_scale_5
[(pixel
>> 10) & 0x1f];
941 *d
++ = FX_rgb_scale_5
[(pixel
>> 5) & 0x1f];
942 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
948 else if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
949 /* convert 5R6G5B into 8R8G8B8A */
951 const GLint halfWidth
= width
>> 1;
952 const GLint extraPixel
= (width
& 1);
953 for (row
= 0; row
< height
; row
++) {
955 for (col
= 0; col
< halfWidth
; col
++) {
956 const GLuint pixel
= ((const GLuint
*) src
)[col
];
957 *d
++ = FX_rgb_scale_5
[(pixel
>> 10) & 0x1f];
958 *d
++ = FX_rgb_scale_5
[(pixel
>> 5) & 0x1f];
959 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
960 *d
++ = (pixel
& 0x8000) ? 255 : 0;
961 *d
++ = FX_rgb_scale_5
[(pixel
>> 26) & 0x1f];
962 *d
++ = FX_rgb_scale_5
[(pixel
>> 21) & 0x1f];
963 *d
++ = FX_rgb_scale_5
[(pixel
>> 16) & 0x1f];
964 *d
++ = (pixel
& 0x80000000) ? 255 : 0;
967 const GLushort pixel
= src
[width
- 1];
968 *d
++ = FX_rgb_scale_5
[(pixel
>> 10) & 0x1f];
969 *d
++ = FX_rgb_scale_5
[(pixel
>> 5) & 0x1f];
970 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
971 *d
++ = (pixel
& 0x8000) ? 255 : 0;
977 else if (format
== GL_BGRA
&& type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
978 /* directly memcpy 5R5G5B pixels into client's buffer */
979 const GLint widthInBytes
= width
* 2;
981 for (row
= 0; row
< height
; row
++) {
982 MEMCPY(dst
, src
, widthInBytes
);
988 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
990 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
995 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
1002 fxDDReadPixels8888 (GLcontext
* ctx
,
1004 GLsizei width
, GLsizei height
,
1005 GLenum format
, GLenum type
,
1006 const struct gl_pixelstore_attrib
*packing
,
1009 if (ctx
->_ImageTransferState
/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) {
1010 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
1015 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1019 info
.size
= sizeof(info
);
1020 if (grLfbLock(GR_LFB_READ_ONLY
,
1022 GR_LFBWRITEMODE_ANY
,
1023 GR_ORIGIN_UPPER_LEFT
, FXFALSE
, &info
)) {
1024 const GLint winX
= 0;
1025 const GLint winY
= fxMesa
->height
- 1;
1026 const GLint srcStride
= info
.strideInBytes
/ 4; /* stride in GLuints */
1027 const GLuint
*src
= (const GLuint
*) info
.lfbPtr
1028 + (winY
- y
) * srcStride
+ (winX
+ x
);
1029 GLubyte
*dst
= (GLubyte
*) _mesa_image_address(packing
, dstImage
,
1030 width
, height
, format
,
1033 _mesa_image_row_stride(packing
, width
, format
, type
);
1035 if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1036 /* convert 8A8R8G8B into 8R8G8B */
1038 for (row
= 0; row
< height
; row
++) {
1040 for (col
= 0; col
< width
; col
++) {
1041 const GLuint pixel
= ((const GLuint
*) src
)[col
];
1050 else if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1051 /* 8A8R8G8B pixels into client's buffer */
1053 for (row
= 0; row
< height
; row
++) {
1055 for (col
= 0; col
< width
; col
++) {
1056 const GLuint pixel
= ((const GLuint
*) src
)[col
];
1066 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
1067 /* convert 8A8R8G8B into 5R6G5B */
1069 for (row
= 0; row
< height
; row
++) {
1070 GLushort
*d
= (GLushort
*)dst
;
1071 for (col
= 0; col
< width
; col
++) {
1072 const GLuint pixel
= ((const GLuint
*) src
)[col
];
1073 *d
++ = (((pixel
>> 16) & 0xf8) << 8) |
1074 (((pixel
>> 8) & 0xfc) << 3) |
1075 ((pixel
& 0xf8) >> 3);
1082 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
1084 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
1089 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
1097 fxDDDrawPixels555 (GLcontext
* ctx
, GLint x
, GLint y
,
1098 GLsizei width
, GLsizei height
,
1099 GLenum format
, GLenum type
,
1100 const struct gl_pixelstore_attrib
*unpack
,
1101 const GLvoid
* pixels
)
1103 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1104 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1106 const struct gl_pixelstore_attrib
*finalUnpack
;
1107 struct gl_pixelstore_attrib scissoredUnpack
;
1109 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
1110 ctx
->Pixel
.ZoomY
!= 1.0F
||
1111 (ctx
->_ImageTransferState
& (IMAGE_SCALE_BIAS_BIT
|
1112 IMAGE_MAP_COLOR_BIT
)) ||
1113 (swrast
->_RasterMask
& (ALPHATEST_BIT
|
1114 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
1115 DEPTH_BIT
| /* could be done with RGB:DEPTH */
1116 FOG_BIT
| /* could be done with RGB:DEPTH */
1118 /*CLIP_BIT |*/ /* clipping ok, below */
1123 OCCLUSION_BIT
| /* nope! at least not yet */
1128 _swrast_DrawPixels( ctx
, x
, y
, width
, height
, format
, type
,
1133 /* make sure the pixelpipe is configured correctly */
1134 fxSetupFXUnits(ctx
);
1136 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
1137 if (ctx
->Scissor
.Enabled
) {
1138 /* This is a bit tricky, but by carefully adjusting the px, py,
1139 * width, height, skipPixels and skipRows values we can do
1140 * scissoring without special code in the rendering loop.
1143 /* we'll construct a new pixelstore struct */
1144 finalUnpack
= &scissoredUnpack
;
1145 scissoredUnpack
= *unpack
;
1146 if (scissoredUnpack
.RowLength
== 0)
1147 scissoredUnpack
.RowLength
= width
;
1150 if (x
< ctx
->Scissor
.X
) {
1151 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- x
);
1152 width
-= (ctx
->Scissor
.X
- x
);
1156 if (x
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
1157 width
-= (x
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
1160 if (y
< ctx
->Scissor
.Y
) {
1161 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- y
);
1162 height
-= (ctx
->Scissor
.Y
- y
);
1166 if (y
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
1167 height
-= (y
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
1170 if (width
<= 0 || height
<= 0)
1174 finalUnpack
= unpack
;
1177 info
.size
= sizeof(info
);
1178 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
1180 GR_LFBWRITEMODE_1555
,
1181 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
1182 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1187 const GLint winX
= 0;
1188 const GLint winY
= 0;
1190 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
1191 GLushort
*dst
= (GLushort
*) info
.lfbPtr
+ (winY
+ y
) * dstStride
+ (winX
+ x
);
1193 if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1195 for (row
= 0; row
< height
; row
++) {
1196 GLubyte
*src
= (GLubyte
*) _mesa_image_address(finalUnpack
, pixels
,
1197 width
, height
, format
,
1200 for (col
= 0; col
< width
; col
++) {
1201 dst
[col
] = TDFXPACKCOLOR1555(src
[2], src
[1], src
[0], src
[3]);
1207 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1209 for (row
= 0; row
< height
; row
++) {
1210 GLubyte
*src
= (GLubyte
*) _mesa_image_address(finalUnpack
, pixels
,
1211 width
, height
, format
,
1214 for (col
= 0; col
< width
; col
++) {
1215 dst
[col
] = TDFXPACKCOLOR1555(src
[2], src
[1], src
[0], 255);
1222 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1223 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1229 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1234 fxDDDrawPixels565 (GLcontext
* ctx
, GLint x
, GLint y
,
1235 GLsizei width
, GLsizei height
,
1236 GLenum format
, GLenum type
,
1237 const struct gl_pixelstore_attrib
*unpack
,
1238 const GLvoid
* pixels
)
1240 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1241 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1243 const struct gl_pixelstore_attrib
*finalUnpack
;
1244 struct gl_pixelstore_attrib scissoredUnpack
;
1246 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
1247 ctx
->Pixel
.ZoomY
!= 1.0F
||
1248 (ctx
->_ImageTransferState
& (IMAGE_SCALE_BIAS_BIT
|
1249 IMAGE_MAP_COLOR_BIT
)) ||
1250 (swrast
->_RasterMask
& (ALPHATEST_BIT
|
1251 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
1252 DEPTH_BIT
| /* could be done with RGB:DEPTH */
1253 FOG_BIT
| /* could be done with RGB:DEPTH */
1255 /*CLIP_BIT |*/ /* clipping ok, below */
1260 OCCLUSION_BIT
| /* nope! at least not yet */
1265 _swrast_DrawPixels( ctx
, x
, y
, width
, height
, format
, type
,
1270 /* make sure the pixelpipe is configured correctly */
1271 fxSetupFXUnits(ctx
);
1273 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
1274 if (ctx
->Scissor
.Enabled
) {
1275 /* This is a bit tricky, but by carefully adjusting the px, py,
1276 * width, height, skipPixels and skipRows values we can do
1277 * scissoring without special code in the rendering loop.
1280 /* we'll construct a new pixelstore struct */
1281 finalUnpack
= &scissoredUnpack
;
1282 scissoredUnpack
= *unpack
;
1283 if (scissoredUnpack
.RowLength
== 0)
1284 scissoredUnpack
.RowLength
= width
;
1287 if (x
< ctx
->Scissor
.X
) {
1288 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- x
);
1289 width
-= (ctx
->Scissor
.X
- x
);
1293 if (x
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
1294 width
-= (x
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
1297 if (y
< ctx
->Scissor
.Y
) {
1298 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- y
);
1299 height
-= (ctx
->Scissor
.Y
- y
);
1303 if (y
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
1304 height
-= (y
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
1307 if (width
<= 0 || height
<= 0)
1311 finalUnpack
= unpack
;
1314 info
.size
= sizeof(info
);
1315 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
1317 GR_LFBWRITEMODE_565
,
1318 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
1319 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1324 const GLint winX
= 0;
1325 const GLint winY
= 0;
1327 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
1328 GLushort
*dst
= (GLushort
*) info
.lfbPtr
+ (winY
+ y
) * dstStride
+ (winX
+ x
);
1330 if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1332 for (row
= 0; row
< height
; row
++) {
1333 GLubyte
*src
= (GLubyte
*) _mesa_image_address(finalUnpack
, pixels
,
1334 width
, height
, format
,
1337 for (col
= 0; col
< width
; col
++) {
1338 dst
[col
] = TDFXPACKCOLOR565(src
[2], src
[1], src
[0]);
1344 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1346 for (row
= 0; row
< height
; row
++) {
1347 GLubyte
*src
= (GLubyte
*) _mesa_image_address(finalUnpack
, pixels
,
1348 width
, height
, format
,
1351 for (col
= 0; col
< width
; col
++) {
1352 dst
[col
] = TDFXPACKCOLOR565(src
[2], src
[1], src
[0]);
1359 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1360 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1366 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1371 fxDDDrawPixels565_rev (GLcontext
* ctx
, GLint x
, GLint y
,
1372 GLsizei width
, GLsizei height
,
1373 GLenum format
, GLenum type
,
1374 const struct gl_pixelstore_attrib
*unpack
,
1375 const GLvoid
* pixels
)
1377 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1378 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1380 const struct gl_pixelstore_attrib
*finalUnpack
;
1381 struct gl_pixelstore_attrib scissoredUnpack
;
1383 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
1384 ctx
->Pixel
.ZoomY
!= 1.0F
||
1385 (ctx
->_ImageTransferState
& (IMAGE_SCALE_BIAS_BIT
|
1386 IMAGE_MAP_COLOR_BIT
)) ||
1387 (swrast
->_RasterMask
& (ALPHATEST_BIT
|
1388 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
1389 DEPTH_BIT
| /* could be done with RGB:DEPTH */
1390 FOG_BIT
| /* could be done with RGB:DEPTH */
1392 /*CLIP_BIT |*/ /* clipping ok, below */
1397 OCCLUSION_BIT
| /* nope! at least not yet */
1402 _swrast_DrawPixels( ctx
, x
, y
, width
, height
, format
, type
,
1407 /* make sure the pixelpipe is configured correctly */
1408 fxSetupFXUnits(ctx
);
1410 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
1411 if (ctx
->Scissor
.Enabled
) {
1412 /* This is a bit tricky, but by carefully adjusting the px, py,
1413 * width, height, skipPixels and skipRows values we can do
1414 * scissoring without special code in the rendering loop.
1417 /* we'll construct a new pixelstore struct */
1418 finalUnpack
= &scissoredUnpack
;
1419 scissoredUnpack
= *unpack
;
1420 if (scissoredUnpack
.RowLength
== 0)
1421 scissoredUnpack
.RowLength
= width
;
1424 if (x
< ctx
->Scissor
.X
) {
1425 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- x
);
1426 width
-= (ctx
->Scissor
.X
- x
);
1430 if (x
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
1431 width
-= (x
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
1434 if (y
< ctx
->Scissor
.Y
) {
1435 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- y
);
1436 height
-= (ctx
->Scissor
.Y
- y
);
1440 if (y
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
1441 height
-= (y
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
1444 if (width
<= 0 || height
<= 0)
1448 finalUnpack
= unpack
;
1451 info
.size
= sizeof(info
);
1452 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
1454 GR_LFBWRITEMODE_565
,
1455 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
1456 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1461 const GLint winX
= 0;
1462 const GLint winY
= 0;
1464 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
1465 GLushort
*dst
= (GLushort
*) info
.lfbPtr
+ (winY
+ y
) * dstStride
+ (winX
+ x
);
1467 if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1469 for (row
= 0; row
< height
; row
++) {
1470 GLubyte
*src
= (GLubyte
*) _mesa_image_address(finalUnpack
, pixels
,
1471 width
, height
, format
,
1474 for (col
= 0; col
< width
; col
++) {
1475 dst
[col
] = TDFXPACKCOLOR565(src
[0], src
[1], src
[2]);
1481 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1483 for (row
= 0; row
< height
; row
++) {
1484 GLubyte
*src
= (GLubyte
*) _mesa_image_address(finalUnpack
, pixels
,
1485 width
, height
, format
,
1488 for (col
= 0; col
< width
; col
++) {
1489 dst
[col
] = TDFXPACKCOLOR565(src
[0], src
[1], src
[2]);
1496 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1497 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1503 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1508 fxDDDrawPixels8888 (GLcontext
* ctx
, GLint x
, GLint y
,
1509 GLsizei width
, GLsizei height
,
1510 GLenum format
, GLenum type
,
1511 const struct gl_pixelstore_attrib
*unpack
,
1512 const GLvoid
* pixels
)
1514 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1515 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1517 const struct gl_pixelstore_attrib
*finalUnpack
;
1518 struct gl_pixelstore_attrib scissoredUnpack
;
1520 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
1521 ctx
->Pixel
.ZoomY
!= 1.0F
||
1522 (ctx
->_ImageTransferState
& (IMAGE_SCALE_BIAS_BIT
|
1523 IMAGE_MAP_COLOR_BIT
)) ||
1524 (swrast
->_RasterMask
& (/*ALPHATEST_BIT |*/
1525 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
1526 DEPTH_BIT
| /* could be done with RGB:DEPTH */
1527 FOG_BIT
| /* could be done with RGB:DEPTH */
1529 /*CLIP_BIT |*/ /* clipping ok, below */
1531 /*MASKING_BIT |*/ /* masking ok, we're in 32bpp */
1532 /*ALPHABUF_BIT |*//* alpha ok, we're in 32bpp */
1534 OCCLUSION_BIT
| /* nope! at least not yet */
1539 _swrast_DrawPixels( ctx
, x
, y
, width
, height
, format
, type
,
1544 /* make sure the pixelpipe is configured correctly */
1545 fxSetupFXUnits(ctx
);
1547 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
1548 if (ctx
->Scissor
.Enabled
) {
1549 /* This is a bit tricky, but by carefully adjusting the px, py,
1550 * width, height, skipPixels and skipRows values we can do
1551 * scissoring without special code in the rendering loop.
1554 /* we'll construct a new pixelstore struct */
1555 finalUnpack
= &scissoredUnpack
;
1556 scissoredUnpack
= *unpack
;
1557 if (scissoredUnpack
.RowLength
== 0)
1558 scissoredUnpack
.RowLength
= width
;
1561 if (x
< ctx
->Scissor
.X
) {
1562 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- x
);
1563 width
-= (ctx
->Scissor
.X
- x
);
1567 if (x
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
1568 width
-= (x
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
1571 if (y
< ctx
->Scissor
.Y
) {
1572 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- y
);
1573 height
-= (ctx
->Scissor
.Y
- y
);
1577 if (y
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
1578 height
-= (y
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
1581 if (width
<= 0 || height
<= 0)
1585 finalUnpack
= unpack
;
1588 info
.size
= sizeof(info
);
1589 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
1591 GR_LFBWRITEMODE_8888
,
1592 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
1593 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1598 const GLint winX
= 0;
1599 const GLint winY
= 0;
1601 const GLint dstStride
= info
.strideInBytes
/ 4; /* stride in GLuints */
1602 GLuint
*dst
= (GLuint
*) info
.lfbPtr
+ (winY
+ y
) * dstStride
+ (winX
+ x
);
1604 if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1605 /* directly memcpy 8A8R8G8B pixels to screen */
1606 const GLint widthInBytes
= width
* 4;
1608 for (row
= 0; row
< height
; row
++) {
1609 GLubyte
*src
= (GLubyte
*) _mesa_image_address(finalUnpack
, pixels
,
1610 width
, height
, format
,
1612 MEMCPY(dst
, src
, widthInBytes
);
1616 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1618 for (row
= 0; row
< height
; row
++) {
1619 GLubyte
*src
= (GLubyte
*) _mesa_image_address(finalUnpack
, pixels
,
1620 width
, height
, format
,
1623 for (col
= 0; col
< width
; col
++) {
1624 dst
[col
] = TDFXPACKCOLOR8888(src
[2], src
[1], src
[0], 255);
1631 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1632 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1638 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1643 fxDDFinish(GLcontext
* ctx
)
1652 /* KW: Put the word Mesa in the render string because quakeworld
1653 * checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE).
1656 static const GLubyte
*
1657 fxDDGetString(GLcontext
* ctx
, GLenum name
)
1659 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1663 return (GLubyte
*)fxMesa
->rendererString
;
1664 #if __WIN32__ /* hack to advertise vanilla extension names */
1666 if (ctx
->Extensions
.String
== NULL
) {
1667 GLubyte
*ext
= _mesa_make_extension_string(ctx
);
1669 ctx
->Extensions
.String
= _mesa_malloc(strlen((char *)ext
) + 256);
1670 if (ctx
->Extensions
.String
!= NULL
) {
1671 strcpy((char *)ctx
->Extensions
.String
, (char *)ext
);
1672 /* put any additional extension names here */
1674 strcat((char *)ctx
->Extensions
.String
, " 3DFX_set_global_palette");
1677 strcat((char *)ctx
->Extensions
.String
, " WGL_3DFX_gamma_control");
1678 strcat((char *)ctx
->Extensions
.String
, " WGL_EXT_swap_control");
1679 strcat((char *)ctx
->Extensions
.String
, " WGL_EXT_extensions_string WGL_ARB_extensions_string");
1681 /* put any additional extension names here */
1684 ctx
->Extensions
.String
= ext
;
1688 return ctx
->Extensions
.String
;
1695 static const struct tnl_pipeline_stage
*fx_pipeline
[] = {
1696 &_tnl_vertex_transform_stage
, /* TODO: Add the fastpath here */
1697 &_tnl_normal_transform_stage
,
1698 &_tnl_lighting_stage
,
1699 &_tnl_fog_coordinate_stage
,
1701 &_tnl_texture_transform_stage
,
1702 &_tnl_point_attenuation_stage
,
1703 #if defined(FEATURE_NV_vertex_program) || defined(FEATURE_ARB_vertex_program)
1704 &_tnl_vertex_program_stage
,
1714 fxDDInitFxMesaContext(fxMesaContext fxMesa
)
1717 GLcontext
*ctx
= fxMesa
->glCtx
;
1719 FX_setupGrVertexLayout();
1721 fxMesa
->color
= 0xffffffff;
1725 fxMesa
->stats
.swapBuffer
= 0;
1726 fxMesa
->stats
.reqTexUpload
= 0;
1727 fxMesa
->stats
.texUpload
= 0;
1728 fxMesa
->stats
.memTexUpload
= 0;
1730 fxMesa
->tmuSrc
= FX_TMU_NONE
;
1731 fxMesa
->lastUnitsMode
= FX_UM_NONE
;
1734 /* FX units setup */
1736 fxMesa
->unitsState
.alphaTestEnabled
= GL_FALSE
;
1737 fxMesa
->unitsState
.alphaTestFunc
= GL_ALWAYS
;
1738 fxMesa
->unitsState
.alphaTestRefValue
= 0.0;
1740 fxMesa
->unitsState
.blendEnabled
= GL_FALSE
;
1741 fxMesa
->unitsState
.blendSrcFuncRGB
= GR_BLEND_ONE
;
1742 fxMesa
->unitsState
.blendDstFuncRGB
= GR_BLEND_ZERO
;
1743 fxMesa
->unitsState
.blendSrcFuncAlpha
= GR_BLEND_ONE
;
1744 fxMesa
->unitsState
.blendDstFuncAlpha
= GR_BLEND_ZERO
;
1745 fxMesa
->unitsState
.blendEqRGB
= GR_BLEND_OP_ADD
;
1746 fxMesa
->unitsState
.blendEqAlpha
= GR_BLEND_OP_ADD
;
1748 fxMesa
->unitsState
.depthTestEnabled
= GL_FALSE
;
1749 fxMesa
->unitsState
.depthMask
= GL_TRUE
;
1750 fxMesa
->unitsState
.depthTestFunc
= GL_LESS
;
1751 fxMesa
->unitsState
.depthBias
= 0;
1753 fxMesa
->unitsState
.stencilWriteMask
= 0xff;
1755 if (fxMesa
->colDepth
== 32) {
1757 fxMesa
->Glide
.grColorMaskExt(FXTRUE
, FXTRUE
, FXTRUE
, fxMesa
->haveHwAlpha
);
1759 /* 15/16 bpp mode */
1760 grColorMask(FXTRUE
, fxMesa
->haveHwAlpha
);
1763 fxMesa
->currentFB
= fxMesa
->haveDoubleBuffer
? GR_BUFFER_BACKBUFFER
: GR_BUFFER_FRONTBUFFER
;
1764 grRenderBuffer(fxMesa
->currentFB
);
1766 fxMesa
->state
= MALLOC(FX_grGetInteger(GR_GLIDE_STATE_SIZE
));
1767 fxMesa
->fogTable
= (GrFog_t
*) MALLOC(FX_grGetInteger(GR_FOG_TABLE_ENTRIES
) *
1770 if (!fxMesa
->state
|| !fxMesa
->fogTable
) {
1772 FREE(fxMesa
->state
);
1773 if (fxMesa
->fogTable
)
1774 FREE(fxMesa
->fogTable
);
1778 if (fxMesa
->haveZBuffer
) {
1779 grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER
);
1782 if (!fxMesa
->bgrOrder
) {
1783 grLfbWriteColorFormat(GR_COLORFORMAT_ABGR
);
1786 if (fxMesa
->Glide
.grSetNumPendingBuffers
!= NULL
) {
1787 fxMesa
->Glide
.grSetNumPendingBuffers(fxMesa
->maxPendingSwapBuffers
);
1790 fxMesa
->textureAlign
= FX_grGetInteger(GR_TEXTURE_ALIGN
);
1794 int textureLevels
= 0;
1795 int textureSize
= FX_grGetInteger(GR_MAX_TEXTURE_SIZE
);
1798 } while ((textureSize
>>= 0x1) & 0x7ff);
1799 ctx
->Const
.MaxTextureLevels
= textureLevels
;
1800 ctx
->Const
.MaxTextureLodBias
= /*textureLevels - 1*/8; /* Glide bug */
1801 #if FX_RESCALE_BIG_TEXURES_HACK
1802 fxMesa
->textureMaxLod
= textureLevels
- 1;
1803 if ((env
= getenv("MESA_FX_MAXLOD")) != NULL
) {
1804 int maxLevels
= atoi(env
) + 1;
1805 if ((maxLevels
<= MAX_TEXTURE_LEVELS
) && (maxLevels
> textureLevels
)) {
1806 ctx
->Const
.MaxTextureLevels
= maxLevels
;
1811 ctx
->Const
.MaxTextureCoordUnits
=
1812 ctx
->Const
.MaxTextureImageUnits
= fxMesa
->haveTwoTMUs
? 2 : 1;
1813 ctx
->Const
.MaxTextureUnits
= MAX2(ctx
->Const
.MaxTextureImageUnits
, ctx
->Const
.MaxTextureCoordUnits
);
1815 fxMesa
->new_state
= _NEW_ALL
;
1816 if (!fxMesa
->haveHwStencil
) {
1817 /* don't touch stencil if there is none */
1818 fxMesa
->new_state
&= ~FX_NEW_STENCIL
;
1821 /* Initialize the software rasterizer and helper modules.
1823 _swrast_CreateContext(ctx
);
1824 _ac_CreateContext(ctx
);
1825 _tnl_CreateContext(ctx
);
1826 _swsetup_CreateContext(ctx
);
1828 /* Install customized pipeline */
1829 _tnl_destroy_pipeline(ctx
);
1830 _tnl_install_pipeline(ctx
, fx_pipeline
);
1834 fxSetupDDPointers(ctx
);
1835 fxDDInitTriFuncs(ctx
);
1837 /* Tell the software rasterizer to use pixel fog always.
1839 _swrast_allow_vertex_fog(ctx
, GL_FALSE
);
1840 _swrast_allow_pixel_fog(ctx
, GL_TRUE
);
1841 _tnl_allow_vertex_fog( ctx
, GL_FALSE
);
1842 _tnl_allow_pixel_fog( ctx
, GL_TRUE
);
1844 /* Tell tnl not to calculate or use vertex fog factors. (Needed to
1845 * tell render stage not to clip fog coords).
1847 /* _tnl_calculate_vertex_fog( ctx, GL_FALSE ); */
1849 fxDDInitExtensions(ctx
);
1852 /* do we want dither? It just looks bad... */
1853 grEnable(GR_ALLOW_MIPMAP_DITHER
);
1855 grGlideGetState((GrState
*) fxMesa
->state
);
1863 fxDDDestroyFxMesaContext(fxMesaContext fxMesa
)
1865 _swsetup_DestroyContext(fxMesa
->glCtx
);
1866 _tnl_DestroyContext(fxMesa
->glCtx
);
1867 _ac_DestroyContext(fxMesa
->glCtx
);
1868 _swrast_DestroyContext(fxMesa
->glCtx
);
1871 FREE(fxMesa
->state
);
1872 if (fxMesa
->fogTable
)
1873 FREE(fxMesa
->fogTable
);
1874 fxFreeVB(fxMesa
->glCtx
);
1881 fxDDInitExtensions(GLcontext
* ctx
)
1883 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1885 #if 1 /* multipass ColorSum stage */
1886 _mesa_enable_extension(ctx
, "GL_EXT_secondary_color");
1889 _mesa_enable_extension(ctx
, "GL_ARB_point_sprite");
1890 _mesa_enable_extension(ctx
, "GL_EXT_point_parameters");
1891 _mesa_enable_extension(ctx
, "GL_EXT_paletted_texture");
1892 _mesa_enable_extension(ctx
, "GL_EXT_texture_lod_bias");
1893 _mesa_enable_extension(ctx
, "GL_EXT_shared_texture_palette");
1894 _mesa_enable_extension(ctx
, "GL_EXT_blend_func_separate");
1895 _mesa_enable_extension(ctx
, "GL_EXT_texture_env_add");
1897 if (fxMesa
->haveTwoTMUs
) {
1898 _mesa_enable_extension(ctx
, "GL_ARB_multitexture");
1901 if (fxMesa
->haveHwStencil
) {
1902 _mesa_enable_extension( ctx
, "GL_EXT_stencil_wrap" );
1905 /* [dBorca] Hack alert:
1906 * True texture compression can be done only on Napalm.
1907 * We will advertise, however, generic texture compression
1908 * on all Voodoo cards; the Mesa logic allows us to eventually
1909 * fallback to uncompressed. This will fix those dumb applications
1910 * which refuse to run w/o texture compression! We actually _can_
1911 * do texture compression for pre-Napalm cores, through NCC. But
1912 * NCC poses many issues:
1913 * 1) NCC w/o DITHER_ERR has poor quality and NCC w/ DITHER_ERR is
1915 * 2) NCC compression cannot be used with multitexturing, because
1916 * the decompression tables are not per TMU anymore (bear in mind
1917 * that earlier Voodoos could handle 2 NCC tables for each TMU --
1918 * just look for POINTCAST_PALETTE). As a last resort, we could
1919 * fake NCC multitexturing through multipass rendering, but...
1920 * ohwell, it's not worth the effort...
1921 * This stand true for multitexturing palletized textures.
1922 * 3) since NCC is not an OpenGL standard (as opposed to FXT1/DXTC), we
1923 * can't use precompressed textures!
1925 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1926 _mesa_enable_extension(ctx
, "GL_ARB_texture_compression");
1927 _mesa_enable_extension(ctx
, "GL_3DFX_texture_compression_FXT1");
1928 _mesa_enable_extension(ctx
, "GL_EXT_texture_compression_s3tc");
1929 _mesa_enable_extension(ctx
, "GL_S3_s3tc");
1930 _mesa_enable_extension(ctx
, "GL_NV_blend_square");
1932 if (fxMesa
->HaveTexus2
) {
1933 _mesa_enable_extension(ctx
, "GL_ARB_texture_compression");
1938 /* doesn't like texture compression */
1939 _mesa_enable_extension(ctx
, "GL_SGIS_generate_mipmap");
1942 if (fxMesa
->HaveCmbExt
) {
1943 _mesa_enable_extension(ctx
, "GL_ARB_texture_env_combine");
1944 _mesa_enable_extension(ctx
, "GL_EXT_texture_env_combine");
1947 if (fxMesa
->HavePixExt
) {
1948 _mesa_enable_extension(ctx
, "GL_EXT_blend_subtract");
1949 _mesa_enable_extension(ctx
, "GL_EXT_blend_equation_separate");
1952 if (fxMesa
->HaveMirExt
) {
1953 _mesa_enable_extension(ctx
, "GL_ARB_texture_mirrored_repeat");
1956 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo2
) {
1957 _mesa_enable_extension(ctx
, "GL_EXT_fog_coord");
1960 /* core-level extensions */
1961 _mesa_enable_extension(ctx
, "GL_EXT_multi_draw_arrays");
1962 _mesa_enable_extension(ctx
, "GL_IBM_multimode_draw_arrays");
1963 _mesa_enable_extension(ctx
, "GL_ARB_vertex_buffer_object");
1966 _mesa_enable_extension(ctx
, "GL_ARB_vertex_program");
1967 _mesa_enable_extension(ctx
, "GL_NV_vertex_program");
1968 _mesa_enable_extension(ctx
, "GL_NV_vertex_program1_1");
1969 _mesa_enable_extension(ctx
, "GL_MESA_program_debug");
1974 /************************************************************************/
1975 /************************************************************************/
1976 /************************************************************************/
1978 /* Check if the hardware supports the current context
1980 * Performs similar work to fxDDChooseRenderState() - should be merged.
1983 fx_check_IsInHardware(GLcontext
* ctx
)
1985 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1987 if (ctx
->RenderMode
!= GL_RENDER
) {
1988 return FX_FALLBACK_RENDER_MODE
;
1991 if (ctx
->Stencil
.Enabled
&& !fxMesa
->haveHwStencil
) {
1992 return FX_FALLBACK_STENCIL
;
1995 if (ctx
->Color
._DrawDestMask
!= DD_FRONT_LEFT_BIT
&&
1996 ctx
->Color
._DrawDestMask
!= DD_BACK_LEFT_BIT
) {
1997 return FX_FALLBACK_DRAW_BUFFER
;
2000 if (ctx
->Color
.BlendEnabled
) {
2001 if (ctx
->Color
.BlendEquationRGB
!= GL_FUNC_ADD
) {
2002 if (!fxMesa
->HavePixExt
||
2003 ((ctx
->Color
.BlendEquationRGB
!= GL_FUNC_SUBTRACT
) &&
2004 (ctx
->Color
.BlendEquationRGB
!= GL_FUNC_REVERSE_SUBTRACT
))) {
2005 return FX_FALLBACK_BLEND
;
2009 if (ctx
->Color
.BlendEquationA
!= GL_FUNC_ADD
) {
2010 if (!fxMesa
->HavePixExt
||
2011 ((ctx
->Color
.BlendEquationA
!= GL_FUNC_SUBTRACT
) &&
2012 (ctx
->Color
.BlendEquationA
!= GL_FUNC_REVERSE_SUBTRACT
))) {
2013 return FX_FALLBACK_BLEND
;
2019 * We fail the spec here, unless certain blending modes:
2020 * (c1 + c2) * 1 + d * 1 = c1 * 1 + d * 1 + c2 * 1
2021 * (c1 + c2) * 1 + d * 0 = c1 * 1 + d * 0 + c2 * 1
2023 if (NEED_SECONDARY_COLOR(ctx
)) {
2024 if ((ctx
->Color
.BlendEquationRGB
!= GL_FUNC_ADD
) &&
2025 (ctx
->Color
.BlendSrcRGB
!= GL_ONE
)) {
2026 /* Can't use multipass to blend ColorSum stage */
2027 return FX_FALLBACK_SPECULAR
;
2034 * We could avoid this for certain `sfactor/dfactor'
2035 * I do not think that is even worthwhile to check
2036 * because if someone is using blending they use more
2037 * interesting settings and also it would add more
2038 * state tracking to a lot of the code.
2040 if (ctx
->Color
.ColorLogicOpEnabled
&& (ctx
->Color
.LogicOp
!= GL_COPY
)) {
2041 return FX_FALLBACK_LOGICOP
;
2044 if ((fxMesa
->colDepth
!= 32) &&
2045 ((ctx
->Color
.ColorMask
[RCOMP
] != ctx
->Color
.ColorMask
[GCOMP
]) ||
2046 (ctx
->Color
.ColorMask
[GCOMP
] != ctx
->Color
.ColorMask
[BCOMP
]))) {
2047 return FX_FALLBACK_COLORMASK
;
2050 /* Unsupported texture/multitexture cases */
2052 /* we can only do 1D/2D textures */
2053 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& ~(TEXTURE_1D_BIT
|TEXTURE_2D_BIT
))
2054 return FX_FALLBACK_TEXTURE_MAP
;
2056 if (fxMesa
->haveTwoTMUs
) {
2057 if (ctx
->Texture
.Unit
[1]._ReallyEnabled
& ~(TEXTURE_1D_BIT
|TEXTURE_2D_BIT
))
2058 return FX_FALLBACK_TEXTURE_MAP
;
2060 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
) {
2061 if (fxMesa
->type
< GR_SSTTYPE_Voodoo2
)
2062 if (ctx
->Texture
.Unit
[0].EnvMode
== GL_BLEND
&&
2063 (ctx
->Texture
.Unit
[1]._ReallyEnabled
||
2064 ctx
->Texture
.Unit
[0].EnvColor
[0] != 0 ||
2065 ctx
->Texture
.Unit
[0].EnvColor
[1] != 0 ||
2066 ctx
->Texture
.Unit
[0].EnvColor
[2] != 0 ||
2067 ctx
->Texture
.Unit
[0].EnvColor
[3] != 1)) {
2068 return FX_FALLBACK_TEXTURE_ENV
;
2070 if (ctx
->Texture
.Unit
[0]._Current
->Image
[0][0]->Border
> 0)
2071 return FX_FALLBACK_TEXTURE_BORDER
;
2074 if (ctx
->Texture
.Unit
[1]._ReallyEnabled
) {
2075 if (fxMesa
->type
< GR_SSTTYPE_Voodoo2
)
2076 if (ctx
->Texture
.Unit
[1].EnvMode
== GL_BLEND
)
2077 return FX_FALLBACK_TEXTURE_ENV
;
2078 if (ctx
->Texture
.Unit
[1]._Current
->Image
[0][0]->Border
> 0)
2079 return FX_FALLBACK_TEXTURE_BORDER
;
2082 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
2083 fprintf(stderr
, "fx_check_IsInHardware: envmode is %s/%s\n",
2084 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[0].EnvMode
),
2085 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[1].EnvMode
));
2087 /* KW: This was wrong (I think) and I changed it... which doesn't mean
2088 * it is now correct...
2089 * BP: The old condition just seemed to test if both texture units
2090 * were enabled. That's easy!
2092 if (ctx
->Texture
._EnabledUnits
== 0x3) {
2094 /* Can't use multipass to blend a multitextured triangle - fall
2097 if (!fxMesa
->haveTwoTMUs
&& ctx
->Color
.BlendEnabled
) {
2098 return FX_FALLBACK_TEXTURE_MULTI
;
2102 if ((ctx
->Texture
.Unit
[0].EnvMode
!= ctx
->Texture
.Unit
[1].EnvMode
) &&
2103 (ctx
->Texture
.Unit
[0].EnvMode
!= GL_MODULATE
) &&
2104 (ctx
->Texture
.Unit
[0].EnvMode
!= GL_REPLACE
)) { /* q2, seems ok... */
2105 if (TDFX_DEBUG
& VERBOSE_DRIVER
)
2106 fprintf(stderr
, "fx_check_IsInHardware: unsupported multitex env mode\n");
2107 return FX_FALLBACK_TEXTURE_MULTI
;
2112 /* we have just one texture unit */
2113 if (ctx
->Texture
._EnabledUnits
> 0x1) {
2114 return FX_FALLBACK_TEXTURE_MULTI
;
2117 if (fxMesa
->type
< GR_SSTTYPE_Voodoo2
)
2118 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
&&
2119 (ctx
->Texture
.Unit
[0].EnvMode
== GL_BLEND
)) {
2120 return FX_FALLBACK_TEXTURE_ENV
;
2130 fxDDUpdateDDPointers(GLcontext
* ctx
, GLuint new_state
)
2132 /* TNLcontext *tnl = TNL_CONTEXT(ctx);*/
2133 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2135 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
2136 fprintf(stderr
, "fxDDUpdateDDPointers(%08x)\n", new_state
);
2139 _swrast_InvalidateState(ctx
, new_state
);
2140 _ac_InvalidateState(ctx
, new_state
);
2141 _tnl_InvalidateState(ctx
, new_state
);
2142 _swsetup_InvalidateState(ctx
, new_state
);
2144 fxMesa
->new_gl_state
|= new_state
;
2151 fxSetupDDPointers(GLcontext
* ctx
)
2153 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2154 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
2156 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
2157 fprintf(stderr
, "fxSetupDDPointers()\n");
2160 ctx
->Driver
.UpdateState
= fxDDUpdateDDPointers
;
2161 ctx
->Driver
.GetString
= fxDDGetString
;
2162 ctx
->Driver
.ClearIndex
= NULL
;
2163 ctx
->Driver
.ClearColor
= fxDDClearColor
;
2164 ctx
->Driver
.Clear
= fxDDClear
;
2165 ctx
->Driver
.DrawBuffer
= fxDDSetDrawBuffer
;
2166 ctx
->Driver
.GetBufferSize
= fxDDBufferSize
;
2167 switch (fxMesa
->colDepth
) {
2169 ctx
->Driver
.DrawPixels
= fxDDDrawPixels555
;
2170 ctx
->Driver
.ReadPixels
= fxDDReadPixels555
;
2171 ctx
->Driver
.Bitmap
= fxDDDrawBitmap2
;
2174 ctx
->Driver
.DrawPixels
= !fxMesa
->bgrOrder
? fxDDDrawPixels565
: fxDDDrawPixels565_rev
;
2175 ctx
->Driver
.ReadPixels
= fxDDReadPixels565
;
2176 ctx
->Driver
.Bitmap
= fxDDDrawBitmap2
;
2179 ctx
->Driver
.DrawPixels
= fxDDDrawPixels8888
;
2180 ctx
->Driver
.ReadPixels
= fxDDReadPixels8888
;
2181 ctx
->Driver
.Bitmap
= fxDDDrawBitmap4
;
2184 ctx
->Driver
.Finish
= fxDDFinish
;
2185 ctx
->Driver
.Flush
= NULL
;
2186 ctx
->Driver
.ChooseTextureFormat
= fxDDChooseTextureFormat
;
2187 ctx
->Driver
.TexImage1D
= fxDDTexImage1D
;
2188 ctx
->Driver
.TexImage2D
= fxDDTexImage2D
;
2189 ctx
->Driver
.TexSubImage1D
= fxDDTexSubImage1D
;
2190 ctx
->Driver
.TexSubImage2D
= fxDDTexSubImage2D
;
2191 ctx
->Driver
.CompressedTexImage2D
= fxDDCompressedTexImage2D
;
2192 ctx
->Driver
.CompressedTexSubImage2D
= fxDDCompressedTexSubImage2D
;
2193 ctx
->Driver
.TestProxyTexImage
= fxDDTestProxyTexImage
;
2194 ctx
->Driver
.TexEnv
= fxDDTexEnv
;
2195 ctx
->Driver
.TexParameter
= fxDDTexParam
;
2196 ctx
->Driver
.BindTexture
= fxDDTexBind
;
2197 ctx
->Driver
.DeleteTexture
= fxDDTexDel
;
2198 ctx
->Driver
.IsTextureResident
= fxDDIsTextureResident
;
2199 ctx
->Driver
.UpdateTexturePalette
= fxDDTexPalette
;
2200 ctx
->Driver
.AlphaFunc
= fxDDAlphaFunc
;
2201 ctx
->Driver
.BlendFuncSeparate
= fxDDBlendFuncSeparate
;
2202 ctx
->Driver
.BlendEquationSeparate
= fxDDBlendEquationSeparate
;
2203 ctx
->Driver
.DepthFunc
= fxDDDepthFunc
;
2204 ctx
->Driver
.DepthMask
= fxDDDepthMask
;
2205 ctx
->Driver
.ColorMask
= fxDDColorMask
;
2206 ctx
->Driver
.Fogfv
= fxDDFogfv
;
2207 ctx
->Driver
.Scissor
= fxDDScissor
;
2208 ctx
->Driver
.FrontFace
= fxDDFrontFace
;
2209 ctx
->Driver
.CullFace
= fxDDCullFace
;
2210 ctx
->Driver
.ShadeModel
= fxDDShadeModel
;
2211 ctx
->Driver
.Enable
= fxDDEnable
;
2212 if (fxMesa
->haveHwStencil
) {
2213 ctx
->Driver
.StencilFunc
= fxDDStencilFunc
;
2214 ctx
->Driver
.StencilMask
= fxDDStencilMask
;
2215 ctx
->Driver
.StencilOp
= fxDDStencilOp
;
2218 fxSetupDDSpanPointers(ctx
);
2219 fxDDUpdateDDPointers(ctx
, ~0);
2227 * Need this to provide at least one external definition.
2230 extern int gl_fx_dummy_function_dd(void);
2232 gl_fx_dummy_function_dd(void)