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 */
48 #include "extensions.h"
52 #include "swrast/swrast.h"
53 #include "swrast/s_context.h"
54 #include "swrast_setup/swrast_setup.h"
56 #include "tnl/t_context.h"
57 #include "tnl/t_pipeline.h"
62 /* lookup table for scaling 4 bit colors up to 8 bits */
63 GLuint FX_rgb_scale_4
[16] = {
64 0, 17, 34, 51, 68, 85, 102, 119,
65 136, 153, 170, 187, 204, 221, 238, 255
68 /* lookup table for scaling 5 bit colors up to 8 bits */
69 GLuint FX_rgb_scale_5
[32] = {
70 0, 8, 16, 25, 33, 41, 49, 58,
71 66, 74, 82, 90, 99, 107, 115, 123,
72 132, 140, 148, 156, 165, 173, 181, 189,
73 197, 206, 214, 222, 230, 239, 247, 255
76 /* lookup table for scaling 6 bit colors up to 8 bits */
77 GLuint FX_rgb_scale_6
[64] = {
78 0, 4, 8, 12, 16, 20, 24, 28,
79 32, 36, 40, 45, 49, 53, 57, 61,
80 65, 69, 73, 77, 81, 85, 89, 93,
81 97, 101, 105, 109, 113, 117, 121, 125,
82 130, 134, 138, 142, 146, 150, 154, 158,
83 162, 166, 170, 174, 178, 182, 186, 190,
84 194, 198, 202, 206, 210, 215, 219, 223,
85 227, 231, 235, 239, 243, 247, 251, 255
90 * Disable color by masking out R, G, B, A
92 static void fxDisableColor (fxMesaContext fxMesa
)
94 if (fxMesa
->colDepth
== 32) {
96 fxMesa
->Glide
.grColorMaskExt(FXFALSE
, FXFALSE
, FXFALSE
, FXFALSE
);
99 grColorMask(FXFALSE
, FXFALSE
);
104 /**********************************************************************/
105 /***** Miscellaneous functions *****/
106 /**********************************************************************/
108 /* Return buffer size information */
110 fxDDGetBufferSize(GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
112 GET_CURRENT_CONTEXT(ctx
);
113 if (ctx
&& FX_CONTEXT(ctx
)) {
114 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
116 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
117 fprintf(stderr
, "fxDDGetBufferSize(...)\n");
120 *width
= fxMesa
->width
;
121 *height
= fxMesa
->height
;
127 * We only implement this function as a mechanism to check if the
128 * framebuffer size has changed (and update corresponding state).
131 fxDDViewport(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
133 GLuint newWidth
, newHeight
;
134 GLframebuffer
*buffer
= ctx
->WinSysDrawBuffer
;
135 fxDDGetBufferSize( buffer
, &newWidth
, &newHeight
);
136 if (buffer
->Width
!= newWidth
|| buffer
->Height
!= newHeight
) {
137 _mesa_resize_framebuffer(ctx
, buffer
, newWidth
, newHeight
);
142 /* Implements glClearColor() */
144 fxDDClearColor(GLcontext
* ctx
, const GLfloat color
[4])
146 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
149 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
150 fprintf(stderr
, "fxDDClearColor(%f, %f, %f, %f)\n",
151 color
[0], color
[1], color
[2], color
[3]);
154 CLAMPED_FLOAT_TO_UBYTE(col
[0], color
[0]);
155 CLAMPED_FLOAT_TO_UBYTE(col
[1], color
[1]);
156 CLAMPED_FLOAT_TO_UBYTE(col
[2], color
[2]);
157 CLAMPED_FLOAT_TO_UBYTE(col
[3], color
[3]);
159 fxMesa
->clearC
= FXCOLOR4(col
);
160 fxMesa
->clearA
= col
[3];
164 /* Clear the color and/or depth buffers */
165 static void fxDDClear( GLcontext
*ctx
, GLbitfield mask
)
167 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
168 GLbitfield softwareMask
= mask
& (BUFFER_BIT_ACCUM
);
169 const GLuint stencil_size
= fxMesa
->haveHwStencil
? ctx
->Visual
.stencilBits
: 0;
170 const FxU32 clearD
= (FxU32
) (ctx
->DrawBuffer
->_DepthMaxF
* ctx
->Depth
.Clear
);
171 const FxU8 clearS
= (FxU8
) (ctx
->Stencil
.Clear
& 0xff);
173 if ( TDFX_DEBUG
& MESA_VERBOSE
) {
174 fprintf( stderr
, "fxDDClear\n");
177 /* we can't clear accum buffers nor stereo */
178 mask
&= ~(BUFFER_BIT_ACCUM
| BUFFER_BIT_FRONT_RIGHT
| BUFFER_BIT_BACK_RIGHT
);
180 /* Need this check to respond to certain HW updates */
181 if (fxMesa
->new_state
& (FX_NEW_SCISSOR
| FX_NEW_COLOR_MASK
)) {
183 fxSetupColorMask(ctx
);
184 fxMesa
->new_state
&= ~(FX_NEW_SCISSOR
| FX_NEW_COLOR_MASK
);
188 * As per GL spec, color masking should be obeyed when clearing
190 if (ctx
->Visual
.greenBits
!= 8) {
191 /* can only do color masking if running in 24/32bpp on Napalm */
192 if (ctx
->Color
.ColorMask
[RCOMP
] != ctx
->Color
.ColorMask
[GCOMP
] ||
193 ctx
->Color
.ColorMask
[GCOMP
] != ctx
->Color
.ColorMask
[BCOMP
]) {
194 softwareMask
|= (mask
& (BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
));
195 mask
&= ~(BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
);
199 if (fxMesa
->haveHwStencil
) {
201 * If we want to clear stencil, it must be enabled
202 * in the HW, even if the stencil test is not enabled
206 if (mask
& BUFFER_BIT_STENCIL
) {
207 fxMesa
->Glide
.grStencilMaskExt(fxMesa
->unitsState
.stencilWriteMask
);
208 /* set stencil ref value = desired clear value */
209 fxMesa
->Glide
.grStencilFuncExt(GR_CMP_ALWAYS
, clearS
, 0xff);
210 fxMesa
->Glide
.grStencilOpExt(GR_STENCILOP_REPLACE
,
211 GR_STENCILOP_REPLACE
, GR_STENCILOP_REPLACE
);
212 grEnable(GR_STENCIL_MODE_EXT
);
215 grDisable(GR_STENCIL_MODE_EXT
);
218 } else if (mask
& BUFFER_BIT_STENCIL
) {
219 softwareMask
|= (mask
& (BUFFER_BIT_STENCIL
));
220 mask
&= ~(BUFFER_BIT_STENCIL
);
224 * This may be ugly, but it's needed in order to work around a number
230 * This could probably be done fancier but doing each possible case
231 * explicitly is less error prone.
233 switch (mask
& ~BUFFER_BIT_STENCIL
) {
234 case BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_DEPTH
:
235 /* back buffer & depth */
237 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
238 if (stencil_size
> 0) {
239 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
244 grBufferClear(fxMesa
->clearC
,
248 case BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_DEPTH
:
249 /* XXX it appears that the depth buffer isn't cleared when
250 * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
251 * This is a work-around/
255 fxDisableColor(fxMesa
);
256 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
257 if (stencil_size
> 0)
258 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
262 grBufferClear(fxMesa
->clearC
,
265 fxSetupColorMask(ctx
);
266 grDepthMask(FXFALSE
);
268 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
269 if (stencil_size
> 0)
270 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
274 grBufferClear(fxMesa
->clearC
,
278 case BUFFER_BIT_BACK_LEFT
:
279 /* back buffer only */
280 grDepthMask(FXFALSE
);
281 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
282 if (stencil_size
> 0)
283 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
287 grBufferClear(fxMesa
->clearC
,
291 case BUFFER_BIT_FRONT_LEFT
:
292 /* front buffer only */
293 grDepthMask(FXFALSE
);
294 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
295 if (stencil_size
> 0)
296 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
300 grBufferClear(fxMesa
->clearC
,
304 case BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
:
306 grDepthMask(FXFALSE
);
307 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
308 if (stencil_size
> 0)
309 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
313 grBufferClear(fxMesa
->clearC
,
316 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
317 if (stencil_size
> 0)
318 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
322 grBufferClear(fxMesa
->clearC
,
326 case BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_DEPTH
:
327 /* clear back and depth */
329 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
330 if (stencil_size
> 0)
331 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
335 grBufferClear(fxMesa
->clearC
,
339 grDepthMask(FXFALSE
);
340 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
341 if (stencil_size
> 0)
342 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
346 grBufferClear(fxMesa
->clearC
,
350 case BUFFER_BIT_DEPTH
:
351 /* just the depth buffer */
353 fxDisableColor(fxMesa
);
354 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
355 if (stencil_size
> 0)
356 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
360 grBufferClear(fxMesa
->clearC
,
363 fxSetupColorMask(ctx
);
366 /* clear no color buffers or depth buffer but might clear stencil */
367 if ((stencil_size
> 0) && (mask
& BUFFER_BIT_STENCIL
)) {
368 /* XXX need this RenderBuffer call to work around Glide bug */
369 grDepthMask(FXFALSE
);
370 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
371 fxDisableColor(fxMesa
);
372 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
375 fxSetupColorMask(ctx
);
381 if (fxMesa
->haveHwStencil
) {
382 /* We changed the stencil state above. Restore it! */
385 fxSetupDepthTest(ctx
);
386 grRenderBuffer(fxMesa
->currentFB
);
389 _swrast_Clear( ctx
, softwareMask
);
393 /* Set the buffer used for drawing */
394 /* XXX support for separate read/draw buffers hasn't been tested */
395 /* XXX GL_NONE disables color, but fails to correctly maintain state */
397 fxDDSetDrawBuffer(GLcontext
* ctx
, GLenum mode
)
399 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
401 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
402 fprintf(stderr
, "fxDDSetDrawBuffer(%x)\n", (int)mode
);
405 if (mode
== GL_FRONT_LEFT
) {
406 fxMesa
->currentFB
= GR_BUFFER_FRONTBUFFER
;
407 grRenderBuffer(fxMesa
->currentFB
);
409 else if (mode
== GL_BACK_LEFT
) {
410 fxMesa
->currentFB
= GR_BUFFER_BACKBUFFER
;
411 grRenderBuffer(fxMesa
->currentFB
);
413 else if (mode
== GL_NONE
) {
414 fxDisableColor(fxMesa
);
417 /* we'll need a software fallback */
418 /* XXX not implemented */
421 /* update s/w fallback state */
422 _swrast_DrawBuffer(ctx
, mode
);
427 fxDDDrawBitmap2 (GLcontext
*ctx
, GLint px
, GLint py
,
428 GLsizei width
, GLsizei height
,
429 const struct gl_pixelstore_attrib
*unpack
,
430 const GLubyte
*bitmap
)
432 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
433 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
435 GrLfbWriteMode_t mode
;
437 const struct gl_pixelstore_attrib
*finalUnpack
;
438 struct gl_pixelstore_attrib scissoredUnpack
;
440 /* check if there's any raster operations enabled which we can't handle */
441 if (swrast
->_RasterMask
& (ALPHATEST_BIT
|
442 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
443 DEPTH_BIT
| /* could be done with RGB:DEPTH */
444 FOG_BIT
| /* could be done with RGB:DEPTH */
446 /*CLIP_BIT |*/ /* clipping ok, below */
450 OCCLUSION_BIT
| /* nope! at least not yet */
453 _swrast_Bitmap(ctx
, px
, py
, width
, height
, unpack
, bitmap
);
457 /* make sure the pixelpipe is configured correctly */
460 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
461 if (ctx
->Scissor
.Enabled
) {
462 /* This is a bit tricky, but by carefully adjusting the px, py,
463 * width, height, skipPixels and skipRows values we can do
464 * scissoring without special code in the rendering loop.
467 /* we'll construct a new pixelstore struct */
468 finalUnpack
= &scissoredUnpack
;
469 scissoredUnpack
= *unpack
;
470 if (scissoredUnpack
.RowLength
== 0)
471 scissoredUnpack
.RowLength
= width
;
474 if (px
< ctx
->Scissor
.X
) {
475 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- px
);
476 width
-= (ctx
->Scissor
.X
- px
);
480 if (px
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
481 width
-= (px
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
484 if (py
< ctx
->Scissor
.Y
) {
485 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- py
);
486 height
-= (ctx
->Scissor
.Y
- py
);
490 if (py
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
491 height
-= (py
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
494 if (width
<= 0 || height
<= 0)
498 finalUnpack
= unpack
;
501 /* compute pixel value */
503 GLint r
= (GLint
) (ctx
->Current
.RasterColor
[RCOMP
] * 255.0f
);
504 GLint g
= (GLint
) (ctx
->Current
.RasterColor
[GCOMP
] * 255.0f
);
505 GLint b
= (GLint
) (ctx
->Current
.RasterColor
[BCOMP
] * 255.0f
);
506 GLint a
= (GLint
) (ctx
->Current
.RasterColor
[ACOMP
] * 255.0f
);
507 if (fxMesa
->colDepth
== 15) {
508 color
= TDFXPACKCOLOR1555(b
, g
, r
, a
);
509 mode
= GR_LFBWRITEMODE_1555
;
511 color
= fxMesa
->bgrOrder
? TDFXPACKCOLOR565(r
, g
, b
) : TDFXPACKCOLOR565(b
, g
, r
);
512 mode
= GR_LFBWRITEMODE_565
;
516 info
.size
= sizeof(info
);
517 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
520 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
521 _swrast_Bitmap(ctx
, px
, py
, width
, height
, finalUnpack
, bitmap
);
526 const GLint winX
= 0;
527 const GLint winY
= 0;
528 /* The dest stride depends on the hardware and whether we're drawing
529 * to the front or back buffer. This compile-time test seems to do
532 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
535 /* compute dest address of bottom-left pixel in bitmap */
536 GLushort
*dst
= (GLushort
*) info
.lfbPtr
537 + (winY
+ py
) * dstStride
+ (winX
+ px
);
539 for (row
= 0; row
< height
; row
++) {
541 (const GLubyte
*) _mesa_image_address2d(finalUnpack
,
542 bitmap
, width
, height
,
543 GL_COLOR_INDEX
, GL_BITMAP
,
545 if (finalUnpack
->LsbFirst
) {
546 /* least significan bit first */
547 GLubyte mask
= 1U << (finalUnpack
->SkipPixels
& 0x7);
549 for (col
= 0; col
< width
; col
++) {
565 /* most significan bit first */
566 GLubyte mask
= 128U >> (finalUnpack
->SkipPixels
& 0x7);
568 for (col
= 0; col
< width
; col
++) {
587 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
591 fxDDDrawBitmap4 (GLcontext
*ctx
, GLint px
, GLint py
,
592 GLsizei width
, GLsizei height
,
593 const struct gl_pixelstore_attrib
*unpack
,
594 const GLubyte
*bitmap
)
596 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
597 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
600 const struct gl_pixelstore_attrib
*finalUnpack
;
601 struct gl_pixelstore_attrib scissoredUnpack
;
603 /* check if there's any raster operations enabled which we can't handle */
604 if ((swrast
->_RasterMask
& (/*ALPHATEST_BIT |*/
605 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
606 DEPTH_BIT
| /* could be done with RGB:DEPTH */
607 FOG_BIT
| /* could be done with RGB:DEPTH */
609 /*CLIP_BIT |*/ /* clipping ok, below */
611 /*MASKING_BIT |*/ /* masking ok, we're in 32bpp */
613 OCCLUSION_BIT
| /* nope! at least not yet */
617 _swrast_Bitmap(ctx
, px
, py
, width
, height
, unpack
, bitmap
);
621 /* make sure the pixelpipe is configured correctly */
624 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
625 if (ctx
->Scissor
.Enabled
) {
626 /* This is a bit tricky, but by carefully adjusting the px, py,
627 * width, height, skipPixels and skipRows values we can do
628 * scissoring without special code in the rendering loop.
631 /* we'll construct a new pixelstore struct */
632 finalUnpack
= &scissoredUnpack
;
633 scissoredUnpack
= *unpack
;
634 if (scissoredUnpack
.RowLength
== 0)
635 scissoredUnpack
.RowLength
= width
;
638 if (px
< ctx
->Scissor
.X
) {
639 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- px
);
640 width
-= (ctx
->Scissor
.X
- px
);
644 if (px
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
645 width
-= (px
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
648 if (py
< ctx
->Scissor
.Y
) {
649 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- py
);
650 height
-= (ctx
->Scissor
.Y
- py
);
654 if (py
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
655 height
-= (py
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
658 if (width
<= 0 || height
<= 0)
662 finalUnpack
= unpack
;
665 /* compute pixel value */
667 GLint r
= (GLint
) (ctx
->Current
.RasterColor
[RCOMP
] * 255.0f
);
668 GLint g
= (GLint
) (ctx
->Current
.RasterColor
[GCOMP
] * 255.0f
);
669 GLint b
= (GLint
) (ctx
->Current
.RasterColor
[BCOMP
] * 255.0f
);
670 GLint a
= (GLint
) (ctx
->Current
.RasterColor
[ACOMP
] * 255.0f
);
671 color
= TDFXPACKCOLOR8888(b
, g
, r
, a
);
674 info
.size
= sizeof(info
);
675 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
677 GR_LFBWRITEMODE_8888
,
678 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
679 _swrast_Bitmap(ctx
, px
, py
, width
, height
, finalUnpack
, bitmap
);
684 const GLint winX
= 0;
685 const GLint winY
= 0;
686 /* The dest stride depends on the hardware and whether we're drawing
687 * to the front or back buffer. This compile-time test seems to do
690 const GLint dstStride
= info
.strideInBytes
/ 4; /* stride in GLuints */
693 /* compute dest address of bottom-left pixel in bitmap */
694 GLuint
*dst
= (GLuint
*) info
.lfbPtr
695 + (winY
+ py
) * dstStride
+ (winX
+ px
);
697 for (row
= 0; row
< height
; row
++) {
699 (const GLubyte
*) _mesa_image_address2d(finalUnpack
,
700 bitmap
, width
, height
,
701 GL_COLOR_INDEX
, GL_BITMAP
,
703 if (finalUnpack
->LsbFirst
) {
704 /* least significan bit first */
705 GLubyte mask
= 1U << (finalUnpack
->SkipPixels
& 0x7);
707 for (col
= 0; col
< width
; col
++) {
723 /* most significan bit first */
724 GLubyte mask
= 128U >> (finalUnpack
->SkipPixels
& 0x7);
726 for (col
= 0; col
< width
; col
++) {
745 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
750 fxDDReadPixels565 (GLcontext
* ctx
,
752 GLsizei width
, GLsizei height
,
753 GLenum format
, GLenum type
,
754 const struct gl_pixelstore_attrib
*packing
,
757 if (ctx
->_ImageTransferState
/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) {
758 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
763 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
767 info
.size
= sizeof(info
);
768 if (grLfbLock(GR_LFB_READ_ONLY
,
771 GR_ORIGIN_UPPER_LEFT
, FXFALSE
, &info
)) {
772 const GLint winX
= 0;
773 const GLint winY
= fxMesa
->height
- 1;
774 const GLint srcStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
775 const GLushort
*src
= (const GLushort
*) info
.lfbPtr
776 + (winY
- y
) * srcStride
+ (winX
+ x
);
777 GLubyte
*dst
= (GLubyte
*) _mesa_image_address2d(packing
, dstImage
,
778 width
, height
, format
,
781 _mesa_image_row_stride(packing
, width
, format
, type
);
783 if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
784 /* convert 5R6G5B into 8R8G8B */
786 const GLint halfWidth
= width
>> 1;
787 const GLint extraPixel
= (width
& 1);
788 for (row
= 0; row
< height
; row
++) {
790 for (col
= 0; col
< halfWidth
; col
++) {
791 const GLuint pixel
= ((const GLuint
*) src
)[col
];
792 *d
++ = FX_rgb_scale_5
[(pixel
>> 11) & 0x1f];
793 *d
++ = FX_rgb_scale_6
[(pixel
>> 5) & 0x3f];
794 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
795 *d
++ = FX_rgb_scale_5
[(pixel
>> 27) & 0x1f];
796 *d
++ = FX_rgb_scale_6
[(pixel
>> 21) & 0x3f];
797 *d
++ = FX_rgb_scale_5
[(pixel
>> 16) & 0x1f];
800 GLushort pixel
= src
[width
- 1];
801 *d
++ = FX_rgb_scale_5
[(pixel
>> 11) & 0x1f];
802 *d
++ = FX_rgb_scale_6
[(pixel
>> 5) & 0x3f];
803 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
809 else if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
810 /* convert 5R6G5B into 8R8G8B8A */
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];
822 *d
++ = FX_rgb_scale_5
[(pixel
>> 27) & 0x1f];
823 *d
++ = FX_rgb_scale_6
[(pixel
>> 21) & 0x3f];
824 *d
++ = FX_rgb_scale_5
[(pixel
>> 16) & 0x1f];
828 const GLushort pixel
= src
[width
- 1];
829 *d
++ = FX_rgb_scale_5
[(pixel
>> 11) & 0x1f];
830 *d
++ = FX_rgb_scale_6
[(pixel
>> 5) & 0x3f];
831 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
838 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
839 /* directly memcpy 5R6G5B pixels into client's buffer */
840 const GLint widthInBytes
= width
* 2;
842 for (row
= 0; row
< height
; row
++) {
843 MEMCPY(dst
, src
, widthInBytes
);
849 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
851 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
856 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
863 fxDDReadPixels555 (GLcontext
* ctx
,
865 GLsizei width
, GLsizei height
,
866 GLenum format
, GLenum type
,
867 const struct gl_pixelstore_attrib
*packing
,
870 if (ctx
->_ImageTransferState
/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) {
871 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
876 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
880 info
.size
= sizeof(info
);
881 if (grLfbLock(GR_LFB_READ_ONLY
,
884 GR_ORIGIN_UPPER_LEFT
, FXFALSE
, &info
)) {
885 const GLint winX
= 0;
886 const GLint winY
= fxMesa
->height
- 1;
887 const GLint srcStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
888 const GLushort
*src
= (const GLushort
*) info
.lfbPtr
889 + (winY
- y
) * srcStride
+ (winX
+ x
);
890 GLubyte
*dst
= (GLubyte
*) _mesa_image_address2d(packing
, dstImage
,
891 width
, height
, format
,
894 _mesa_image_row_stride(packing
, width
, format
, type
);
896 if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
897 /* convert 5R5G5B into 8R8G8B */
899 const GLint halfWidth
= width
>> 1;
900 const GLint extraPixel
= (width
& 1);
901 for (row
= 0; row
< height
; row
++) {
903 for (col
= 0; col
< halfWidth
; col
++) {
904 const GLuint pixel
= ((const GLuint
*) src
)[col
];
905 *d
++ = FX_rgb_scale_5
[(pixel
>> 10) & 0x1f];
906 *d
++ = FX_rgb_scale_5
[(pixel
>> 5) & 0x1f];
907 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
908 *d
++ = FX_rgb_scale_5
[(pixel
>> 26) & 0x1f];
909 *d
++ = FX_rgb_scale_5
[(pixel
>> 21) & 0x1f];
910 *d
++ = FX_rgb_scale_5
[(pixel
>> 16) & 0x1f];
913 GLushort pixel
= src
[width
- 1];
914 *d
++ = FX_rgb_scale_5
[(pixel
>> 10) & 0x1f];
915 *d
++ = FX_rgb_scale_5
[(pixel
>> 5) & 0x1f];
916 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
922 else if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
923 /* convert 5R6G5B into 8R8G8B8A */
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
++ = (pixel
& 0x8000) ? 255 : 0;
935 *d
++ = FX_rgb_scale_5
[(pixel
>> 26) & 0x1f];
936 *d
++ = FX_rgb_scale_5
[(pixel
>> 21) & 0x1f];
937 *d
++ = FX_rgb_scale_5
[(pixel
>> 16) & 0x1f];
938 *d
++ = (pixel
& 0x80000000) ? 255 : 0;
941 const GLushort pixel
= src
[width
- 1];
942 *d
++ = FX_rgb_scale_5
[(pixel
>> 10) & 0x1f];
943 *d
++ = FX_rgb_scale_5
[(pixel
>> 5) & 0x1f];
944 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
945 *d
++ = (pixel
& 0x8000) ? 255 : 0;
951 else if (format
== GL_BGRA
&& type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
952 /* directly memcpy 5R5G5B pixels into client's buffer */
953 const GLint widthInBytes
= width
* 2;
955 for (row
= 0; row
< height
; row
++) {
956 MEMCPY(dst
, src
, widthInBytes
);
962 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
964 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
969 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
976 fxDDReadPixels8888 (GLcontext
* ctx
,
978 GLsizei width
, GLsizei height
,
979 GLenum format
, GLenum type
,
980 const struct gl_pixelstore_attrib
*packing
,
983 if (ctx
->_ImageTransferState
/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) {
984 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
989 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
993 info
.size
= sizeof(info
);
994 if (grLfbLock(GR_LFB_READ_ONLY
,
997 GR_ORIGIN_UPPER_LEFT
, FXFALSE
, &info
)) {
998 const GLint winX
= 0;
999 const GLint winY
= fxMesa
->height
- 1;
1000 const GLint srcStride
= info
.strideInBytes
/ 4; /* stride in GLuints */
1001 const GLuint
*src
= (const GLuint
*) info
.lfbPtr
1002 + (winY
- y
) * srcStride
+ (winX
+ x
);
1003 GLubyte
*dst
= (GLubyte
*) _mesa_image_address2d(packing
, dstImage
,
1004 width
, height
, format
,
1007 _mesa_image_row_stride(packing
, width
, format
, type
);
1009 if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1010 /* convert 8A8R8G8B into 8R8G8B */
1012 for (row
= 0; row
< height
; row
++) {
1014 for (col
= 0; col
< width
; col
++) {
1015 const GLuint pixel
= ((const GLuint
*) src
)[col
];
1024 else if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1025 /* 8A8R8G8B pixels into client's buffer */
1027 for (row
= 0; row
< height
; row
++) {
1029 for (col
= 0; col
< width
; col
++) {
1030 const GLuint pixel
= ((const GLuint
*) src
)[col
];
1040 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
1041 /* convert 8A8R8G8B into 5R6G5B */
1043 for (row
= 0; row
< height
; row
++) {
1044 GLushort
*d
= (GLushort
*)dst
;
1045 for (col
= 0; col
< width
; col
++) {
1046 const GLuint pixel
= ((const GLuint
*) src
)[col
];
1047 *d
++ = (((pixel
>> 16) & 0xf8) << 8) |
1048 (((pixel
>> 8) & 0xfc) << 3) |
1049 ((pixel
& 0xf8) >> 3);
1056 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
1058 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
1063 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
1071 fxDDDrawPixels555 (GLcontext
* ctx
, GLint x
, GLint y
,
1072 GLsizei width
, GLsizei height
,
1073 GLenum format
, GLenum type
,
1074 const struct gl_pixelstore_attrib
*unpack
,
1075 const GLvoid
* pixels
)
1077 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1078 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1080 const struct gl_pixelstore_attrib
*finalUnpack
;
1081 struct gl_pixelstore_attrib scissoredUnpack
;
1083 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
1084 ctx
->Pixel
.ZoomY
!= 1.0F
||
1085 (ctx
->_ImageTransferState
& (IMAGE_SCALE_BIAS_BIT
|
1086 IMAGE_MAP_COLOR_BIT
)) ||
1087 (swrast
->_RasterMask
& (ALPHATEST_BIT
|
1088 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
1089 DEPTH_BIT
| /* could be done with RGB:DEPTH */
1090 FOG_BIT
| /* could be done with RGB:DEPTH */
1092 /*CLIP_BIT |*/ /* clipping ok, below */
1096 OCCLUSION_BIT
| /* nope! at least not yet */
1101 _swrast_DrawPixels( ctx
, x
, y
, width
, height
, format
, type
,
1106 /* make sure the pixelpipe is configured correctly */
1107 fxSetupFXUnits(ctx
);
1109 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
1110 if (ctx
->Scissor
.Enabled
) {
1111 /* This is a bit tricky, but by carefully adjusting the px, py,
1112 * width, height, skipPixels and skipRows values we can do
1113 * scissoring without special code in the rendering loop.
1116 /* we'll construct a new pixelstore struct */
1117 finalUnpack
= &scissoredUnpack
;
1118 scissoredUnpack
= *unpack
;
1119 if (scissoredUnpack
.RowLength
== 0)
1120 scissoredUnpack
.RowLength
= width
;
1123 if (x
< ctx
->Scissor
.X
) {
1124 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- x
);
1125 width
-= (ctx
->Scissor
.X
- x
);
1129 if (x
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
1130 width
-= (x
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
1133 if (y
< ctx
->Scissor
.Y
) {
1134 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- y
);
1135 height
-= (ctx
->Scissor
.Y
- y
);
1139 if (y
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
1140 height
-= (y
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
1143 if (width
<= 0 || height
<= 0)
1147 finalUnpack
= unpack
;
1150 info
.size
= sizeof(info
);
1151 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
1153 GR_LFBWRITEMODE_1555
,
1154 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
1155 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1160 const GLint winX
= 0;
1161 const GLint winY
= 0;
1163 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
1164 GLushort
*dst
= (GLushort
*) info
.lfbPtr
+ (winY
+ y
) * dstStride
+ (winX
+ x
);
1166 if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1168 for (row
= 0; row
< height
; row
++) {
1169 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1170 pixels
, width
, height
, format
, type
, row
, 0);
1172 for (col
= 0; col
< width
; col
++) {
1173 dst
[col
] = TDFXPACKCOLOR1555(src
[2], src
[1], src
[0], src
[3]);
1179 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1181 for (row
= 0; row
< height
; row
++) {
1182 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1183 pixels
, width
, height
, format
, type
, row
, 0);
1185 for (col
= 0; col
< width
; col
++) {
1186 dst
[col
] = TDFXPACKCOLOR1555(src
[2], src
[1], src
[0], 255);
1193 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1194 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1200 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1205 fxDDDrawPixels565 (GLcontext
* ctx
, GLint x
, GLint y
,
1206 GLsizei width
, GLsizei height
,
1207 GLenum format
, GLenum type
,
1208 const struct gl_pixelstore_attrib
*unpack
,
1209 const GLvoid
* pixels
)
1211 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1212 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1214 const struct gl_pixelstore_attrib
*finalUnpack
;
1215 struct gl_pixelstore_attrib scissoredUnpack
;
1217 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
1218 ctx
->Pixel
.ZoomY
!= 1.0F
||
1219 (ctx
->_ImageTransferState
& (IMAGE_SCALE_BIAS_BIT
|
1220 IMAGE_MAP_COLOR_BIT
)) ||
1221 (swrast
->_RasterMask
& (ALPHATEST_BIT
|
1222 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
1223 DEPTH_BIT
| /* could be done with RGB:DEPTH */
1224 FOG_BIT
| /* could be done with RGB:DEPTH */
1226 /*CLIP_BIT |*/ /* clipping ok, below */
1230 OCCLUSION_BIT
| /* nope! at least not yet */
1235 _swrast_DrawPixels( ctx
, x
, y
, width
, height
, format
, type
,
1240 /* make sure the pixelpipe is configured correctly */
1241 fxSetupFXUnits(ctx
);
1243 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
1244 if (ctx
->Scissor
.Enabled
) {
1245 /* This is a bit tricky, but by carefully adjusting the px, py,
1246 * width, height, skipPixels and skipRows values we can do
1247 * scissoring without special code in the rendering loop.
1250 /* we'll construct a new pixelstore struct */
1251 finalUnpack
= &scissoredUnpack
;
1252 scissoredUnpack
= *unpack
;
1253 if (scissoredUnpack
.RowLength
== 0)
1254 scissoredUnpack
.RowLength
= width
;
1257 if (x
< ctx
->Scissor
.X
) {
1258 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- x
);
1259 width
-= (ctx
->Scissor
.X
- x
);
1263 if (x
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
1264 width
-= (x
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
1267 if (y
< ctx
->Scissor
.Y
) {
1268 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- y
);
1269 height
-= (ctx
->Scissor
.Y
- y
);
1273 if (y
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
1274 height
-= (y
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
1277 if (width
<= 0 || height
<= 0)
1281 finalUnpack
= unpack
;
1284 info
.size
= sizeof(info
);
1285 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
1287 GR_LFBWRITEMODE_565
,
1288 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
1289 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1294 const GLint winX
= 0;
1295 const GLint winY
= 0;
1297 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
1298 GLushort
*dst
= (GLushort
*) info
.lfbPtr
+ (winY
+ y
) * dstStride
+ (winX
+ x
);
1300 if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1302 for (row
= 0; row
< height
; row
++) {
1303 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1304 pixels
, width
, height
, format
, type
, row
, 0);
1306 for (col
= 0; col
< width
; col
++) {
1307 dst
[col
] = TDFXPACKCOLOR565(src
[2], src
[1], src
[0]);
1313 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1315 for (row
= 0; row
< height
; row
++) {
1316 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1317 pixels
, width
, height
, format
, type
, row
, 0);
1319 for (col
= 0; col
< width
; col
++) {
1320 dst
[col
] = TDFXPACKCOLOR565(src
[2], src
[1], src
[0]);
1327 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1328 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1334 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1339 fxDDDrawPixels565_rev (GLcontext
* ctx
, GLint x
, GLint y
,
1340 GLsizei width
, GLsizei height
,
1341 GLenum format
, GLenum type
,
1342 const struct gl_pixelstore_attrib
*unpack
,
1343 const GLvoid
* pixels
)
1345 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1346 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1348 const struct gl_pixelstore_attrib
*finalUnpack
;
1349 struct gl_pixelstore_attrib scissoredUnpack
;
1351 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
1352 ctx
->Pixel
.ZoomY
!= 1.0F
||
1353 (ctx
->_ImageTransferState
& (IMAGE_SCALE_BIAS_BIT
|
1354 IMAGE_MAP_COLOR_BIT
)) ||
1355 (swrast
->_RasterMask
& (ALPHATEST_BIT
|
1356 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
1357 DEPTH_BIT
| /* could be done with RGB:DEPTH */
1358 FOG_BIT
| /* could be done with RGB:DEPTH */
1360 /*CLIP_BIT |*/ /* clipping ok, below */
1364 OCCLUSION_BIT
| /* nope! at least not yet */
1369 _swrast_DrawPixels( ctx
, x
, y
, width
, height
, format
, type
,
1374 /* make sure the pixelpipe is configured correctly */
1375 fxSetupFXUnits(ctx
);
1377 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
1378 if (ctx
->Scissor
.Enabled
) {
1379 /* This is a bit tricky, but by carefully adjusting the px, py,
1380 * width, height, skipPixels and skipRows values we can do
1381 * scissoring without special code in the rendering loop.
1384 /* we'll construct a new pixelstore struct */
1385 finalUnpack
= &scissoredUnpack
;
1386 scissoredUnpack
= *unpack
;
1387 if (scissoredUnpack
.RowLength
== 0)
1388 scissoredUnpack
.RowLength
= width
;
1391 if (x
< ctx
->Scissor
.X
) {
1392 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- x
);
1393 width
-= (ctx
->Scissor
.X
- x
);
1397 if (x
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
1398 width
-= (x
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
1401 if (y
< ctx
->Scissor
.Y
) {
1402 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- y
);
1403 height
-= (ctx
->Scissor
.Y
- y
);
1407 if (y
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
1408 height
-= (y
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
1411 if (width
<= 0 || height
<= 0)
1415 finalUnpack
= unpack
;
1418 info
.size
= sizeof(info
);
1419 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
1421 GR_LFBWRITEMODE_565
,
1422 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
1423 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1428 const GLint winX
= 0;
1429 const GLint winY
= 0;
1431 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
1432 GLushort
*dst
= (GLushort
*) info
.lfbPtr
+ (winY
+ y
) * dstStride
+ (winX
+ x
);
1434 if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1436 for (row
= 0; row
< height
; row
++) {
1437 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1438 pixels
, width
, height
, format
, type
, row
, 0);
1440 for (col
= 0; col
< width
; col
++) {
1441 dst
[col
] = TDFXPACKCOLOR565(src
[0], src
[1], src
[2]);
1447 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1449 for (row
= 0; row
< height
; row
++) {
1450 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1451 pixels
, width
, height
, format
, type
, row
, 0);
1453 for (col
= 0; col
< width
; col
++) {
1454 dst
[col
] = TDFXPACKCOLOR565(src
[0], src
[1], src
[2]);
1461 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1462 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1468 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1473 fxDDDrawPixels8888 (GLcontext
* ctx
, GLint x
, GLint y
,
1474 GLsizei width
, GLsizei height
,
1475 GLenum format
, GLenum type
,
1476 const struct gl_pixelstore_attrib
*unpack
,
1477 const GLvoid
* pixels
)
1479 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1480 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1482 const struct gl_pixelstore_attrib
*finalUnpack
;
1483 struct gl_pixelstore_attrib scissoredUnpack
;
1485 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
1486 ctx
->Pixel
.ZoomY
!= 1.0F
||
1487 (ctx
->_ImageTransferState
& (IMAGE_SCALE_BIAS_BIT
|
1488 IMAGE_MAP_COLOR_BIT
)) ||
1489 (swrast
->_RasterMask
& (/*ALPHATEST_BIT |*/
1490 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
1491 DEPTH_BIT
| /* could be done with RGB:DEPTH */
1492 FOG_BIT
| /* could be done with RGB:DEPTH */
1494 /*CLIP_BIT |*/ /* clipping ok, below */
1496 /*MASKING_BIT |*/ /* masking ok, we're in 32bpp */
1498 OCCLUSION_BIT
| /* nope! at least not yet */
1503 _swrast_DrawPixels( ctx
, x
, y
, width
, height
, format
, type
,
1508 /* make sure the pixelpipe is configured correctly */
1509 fxSetupFXUnits(ctx
);
1511 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
1512 if (ctx
->Scissor
.Enabled
) {
1513 /* This is a bit tricky, but by carefully adjusting the px, py,
1514 * width, height, skipPixels and skipRows values we can do
1515 * scissoring without special code in the rendering loop.
1518 /* we'll construct a new pixelstore struct */
1519 finalUnpack
= &scissoredUnpack
;
1520 scissoredUnpack
= *unpack
;
1521 if (scissoredUnpack
.RowLength
== 0)
1522 scissoredUnpack
.RowLength
= width
;
1525 if (x
< ctx
->Scissor
.X
) {
1526 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- x
);
1527 width
-= (ctx
->Scissor
.X
- x
);
1531 if (x
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
1532 width
-= (x
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
1535 if (y
< ctx
->Scissor
.Y
) {
1536 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- y
);
1537 height
-= (ctx
->Scissor
.Y
- y
);
1541 if (y
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
1542 height
-= (y
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
1545 if (width
<= 0 || height
<= 0)
1549 finalUnpack
= unpack
;
1552 info
.size
= sizeof(info
);
1553 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
1555 GR_LFBWRITEMODE_8888
,
1556 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
1557 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1562 const GLint winX
= 0;
1563 const GLint winY
= 0;
1565 const GLint dstStride
= info
.strideInBytes
/ 4; /* stride in GLuints */
1566 GLuint
*dst
= (GLuint
*) info
.lfbPtr
+ (winY
+ y
) * dstStride
+ (winX
+ x
);
1568 if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1569 /* directly memcpy 8A8R8G8B pixels to screen */
1570 const GLint widthInBytes
= width
* 4;
1572 for (row
= 0; row
< height
; row
++) {
1573 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1574 pixels
, width
, height
, format
, type
, row
, 0);
1575 MEMCPY(dst
, src
, widthInBytes
);
1579 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1581 for (row
= 0; row
< height
; row
++) {
1582 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1583 pixels
, width
, height
, format
, type
, row
, 0);
1585 for (col
= 0; col
< width
; col
++) {
1586 dst
[col
] = TDFXPACKCOLOR8888(src
[2], src
[1], src
[0], 255);
1593 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1594 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1600 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1605 fxDDFinish(GLcontext
* ctx
)
1614 /* KW: Put the word Mesa in the render string because quakeworld
1615 * checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE).
1618 static const GLubyte
*
1619 fxDDGetString(GLcontext
* ctx
, GLenum name
)
1621 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1625 return (GLubyte
*)fxMesa
->rendererString
;
1626 #if __WIN32__ /* hack to advertise vanilla extension names */
1628 if (ctx
->Extensions
.String
== NULL
) {
1629 GLubyte
*ext
= _mesa_make_extension_string(ctx
);
1631 ctx
->Extensions
.String
= _mesa_malloc(strlen((char *)ext
) + 256);
1632 if (ctx
->Extensions
.String
!= NULL
) {
1633 strcpy((char *)ctx
->Extensions
.String
, (char *)ext
);
1634 /* put any additional extension names here */
1636 strcat((char *)ctx
->Extensions
.String
, " 3DFX_set_global_palette");
1639 strcat((char *)ctx
->Extensions
.String
, " WGL_3DFX_gamma_control");
1640 strcat((char *)ctx
->Extensions
.String
, " WGL_EXT_swap_control");
1641 strcat((char *)ctx
->Extensions
.String
, " WGL_EXT_extensions_string WGL_ARB_extensions_string");
1643 /* put any additional extension names here */
1646 ctx
->Extensions
.String
= ext
;
1650 return ctx
->Extensions
.String
;
1657 static const struct tnl_pipeline_stage
*fx_pipeline
[] = {
1658 &_tnl_vertex_transform_stage
, /* XXX todo - Add the fastpath here */
1659 &_tnl_normal_transform_stage
,
1660 &_tnl_lighting_stage
,
1661 &_tnl_fog_coordinate_stage
,
1663 &_tnl_texture_transform_stage
,
1664 &_tnl_point_attenuation_stage
,
1665 #if defined(FEATURE_NV_vertex_program) || defined(FEATURE_ARB_vertex_program)
1666 &_tnl_vertex_program_stage
,
1676 fxDDInitFxMesaContext(fxMesaContext fxMesa
)
1678 GLcontext
*ctx
= fxMesa
->glCtx
;
1680 FX_setupGrVertexLayout();
1682 fxMesa
->color
= 0xffffffff;
1686 fxMesa
->stats
.swapBuffer
= 0;
1687 fxMesa
->stats
.reqTexUpload
= 0;
1688 fxMesa
->stats
.texUpload
= 0;
1689 fxMesa
->stats
.memTexUpload
= 0;
1691 fxMesa
->tmuSrc
= FX_TMU_NONE
;
1692 fxMesa
->lastUnitsMode
= FX_UM_NONE
;
1695 /* FX units setup */
1697 fxMesa
->unitsState
.alphaTestEnabled
= GL_FALSE
;
1698 fxMesa
->unitsState
.alphaTestFunc
= GL_ALWAYS
;
1699 fxMesa
->unitsState
.alphaTestRefValue
= 0.0;
1701 fxMesa
->unitsState
.blendEnabled
= GL_FALSE
;
1702 fxMesa
->unitsState
.blendSrcFuncRGB
= GR_BLEND_ONE
;
1703 fxMesa
->unitsState
.blendDstFuncRGB
= GR_BLEND_ZERO
;
1704 fxMesa
->unitsState
.blendSrcFuncAlpha
= GR_BLEND_ONE
;
1705 fxMesa
->unitsState
.blendDstFuncAlpha
= GR_BLEND_ZERO
;
1706 fxMesa
->unitsState
.blendEqRGB
= GR_BLEND_OP_ADD
;
1707 fxMesa
->unitsState
.blendEqAlpha
= GR_BLEND_OP_ADD
;
1709 fxMesa
->unitsState
.depthTestEnabled
= GL_FALSE
;
1710 fxMesa
->unitsState
.depthMask
= GL_TRUE
;
1711 fxMesa
->unitsState
.depthTestFunc
= GL_LESS
;
1712 fxMesa
->unitsState
.depthBias
= 0;
1714 fxMesa
->unitsState
.stencilWriteMask
= 0xff;
1716 if (fxMesa
->colDepth
== 32) {
1718 fxMesa
->Glide
.grColorMaskExt(FXTRUE
, FXTRUE
, FXTRUE
, fxMesa
->haveHwAlpha
);
1720 /* 15/16 bpp mode */
1721 grColorMask(FXTRUE
, fxMesa
->haveHwAlpha
);
1724 fxMesa
->currentFB
= fxMesa
->haveDoubleBuffer
? GR_BUFFER_BACKBUFFER
: GR_BUFFER_FRONTBUFFER
;
1725 grRenderBuffer(fxMesa
->currentFB
);
1727 fxMesa
->state
= MALLOC(FX_grGetInteger(GR_GLIDE_STATE_SIZE
));
1728 fxMesa
->fogTable
= (GrFog_t
*) MALLOC(FX_grGetInteger(GR_FOG_TABLE_ENTRIES
) *
1731 if (!fxMesa
->state
|| !fxMesa
->fogTable
) {
1733 FREE(fxMesa
->state
);
1734 if (fxMesa
->fogTable
)
1735 FREE(fxMesa
->fogTable
);
1739 if (fxMesa
->haveZBuffer
) {
1740 grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER
);
1743 if (!fxMesa
->bgrOrder
) {
1744 grLfbWriteColorFormat(GR_COLORFORMAT_ABGR
);
1747 if (fxMesa
->Glide
.grSetNumPendingBuffers
!= NULL
) {
1748 fxMesa
->Glide
.grSetNumPendingBuffers(fxMesa
->maxPendingSwapBuffers
);
1751 fxMesa
->textureAlign
= FX_grGetInteger(GR_TEXTURE_ALIGN
);
1755 int textureLevels
= 0;
1756 int textureSize
= FX_grGetInteger(GR_MAX_TEXTURE_SIZE
);
1759 } while ((textureSize
>>= 0x1) & 0x7ff);
1760 ctx
->Const
.MaxTextureLevels
= textureLevels
;
1761 ctx
->Const
.MaxTextureLodBias
= /*textureLevels - 1*/8; /* Glide bug */
1762 #if FX_RESCALE_BIG_TEXURES_HACK
1763 fxMesa
->textureMaxLod
= textureLevels
- 1;
1764 if ((env
= getenv("MESA_FX_MAXLOD")) != NULL
) {
1765 int maxLevels
= atoi(env
) + 1;
1766 if ((maxLevels
<= MAX_TEXTURE_LEVELS
) && (maxLevels
> textureLevels
)) {
1767 ctx
->Const
.MaxTextureLevels
= maxLevels
;
1772 ctx
->Const
.MaxTextureCoordUnits
=
1773 ctx
->Const
.MaxTextureImageUnits
= fxMesa
->haveTwoTMUs
? 2 : 1;
1774 ctx
->Const
.MaxTextureUnits
= MAX2(ctx
->Const
.MaxTextureImageUnits
, ctx
->Const
.MaxTextureCoordUnits
);
1776 fxMesa
->new_state
= _NEW_ALL
;
1777 if (!fxMesa
->haveHwStencil
) {
1778 /* don't touch stencil if there is none */
1779 fxMesa
->new_state
&= ~FX_NEW_STENCIL
;
1782 /* Initialize the software rasterizer and helper modules.
1784 _swrast_CreateContext(ctx
);
1785 _vbo_CreateContext(ctx
);
1786 _tnl_CreateContext(ctx
);
1787 _swsetup_CreateContext(ctx
);
1789 /* Install customized pipeline */
1790 _tnl_destroy_pipeline(ctx
);
1791 _tnl_install_pipeline(ctx
, fx_pipeline
);
1795 fxSetupDDPointers(ctx
);
1796 fxDDInitTriFuncs(ctx
);
1798 /* Tell the software rasterizer to use pixel fog always.
1800 _swrast_allow_vertex_fog(ctx
, GL_FALSE
);
1801 _swrast_allow_pixel_fog(ctx
, GL_TRUE
);
1802 _tnl_allow_vertex_fog( ctx
, GL_FALSE
);
1803 _tnl_allow_pixel_fog( ctx
, GL_TRUE
);
1805 /* Tell tnl not to calculate or use vertex fog factors. (Needed to
1806 * tell render stage not to clip fog coords).
1808 /* _tnl_calculate_vertex_fog( ctx, GL_FALSE ); */
1810 fxDDInitExtensions(ctx
);
1813 /* do we want dither? It just looks bad... */
1814 grEnable(GR_ALLOW_MIPMAP_DITHER
);
1816 grGlideGetState((GrState
*) fxMesa
->state
);
1824 fxDDDestroyFxMesaContext(fxMesaContext fxMesa
)
1826 _swsetup_DestroyContext(fxMesa
->glCtx
);
1827 _tnl_DestroyContext(fxMesa
->glCtx
);
1828 _vbo_DestroyContext(fxMesa
->glCtx
);
1829 _swrast_DestroyContext(fxMesa
->glCtx
);
1832 FREE(fxMesa
->state
);
1833 if (fxMesa
->fogTable
)
1834 FREE(fxMesa
->fogTable
);
1835 fxFreeVB(fxMesa
->glCtx
);
1842 fxDDInitExtensions(GLcontext
* ctx
)
1844 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1846 #if 1 /* multipass ColorSum stage */
1847 _mesa_enable_extension(ctx
, "GL_EXT_secondary_color");
1850 _mesa_enable_extension(ctx
, "GL_ARB_point_sprite");
1851 _mesa_enable_extension(ctx
, "GL_EXT_point_parameters");
1852 _mesa_enable_extension(ctx
, "GL_EXT_paletted_texture");
1853 _mesa_enable_extension(ctx
, "GL_EXT_texture_lod_bias");
1854 _mesa_enable_extension(ctx
, "GL_EXT_shared_texture_palette");
1855 _mesa_enable_extension(ctx
, "GL_EXT_blend_func_separate");
1856 _mesa_enable_extension(ctx
, "GL_EXT_texture_env_add");
1857 _mesa_enable_extension(ctx
, "GL_EXT_stencil_wrap");
1858 _mesa_enable_extension(ctx
, "GL_EXT_stencil_two_side");
1860 if (fxMesa
->haveTwoTMUs
) {
1861 _mesa_enable_extension(ctx
, "GL_ARB_multitexture");
1864 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1865 _mesa_enable_extension(ctx
, "GL_ARB_texture_compression");
1866 _mesa_enable_extension(ctx
, "GL_3DFX_texture_compression_FXT1");
1867 _mesa_enable_extension(ctx
, "GL_EXT_texture_compression_s3tc");
1868 _mesa_enable_extension(ctx
, "GL_S3_s3tc");
1869 _mesa_enable_extension(ctx
, "GL_NV_blend_square");
1872 * We should enable generic texture compression functions,
1873 * but some poorly written apps automatically assume S3TC.
1874 * Binding NCC to GL_COMPRESSED_RGB[A] is an unnecessary hassle,
1875 * since it's slow and ugly (better with palette textures, then).
1876 * Moreover, NCC is not an OpenGL standard, so we can't use
1877 * precompressed textures. Last, but not least, NCC runs amok
1878 * when multitexturing on a Voodoo3 and up (see POINTCAST vs UMA).
1879 * Note: this is also a problem with palette textures, but
1880 * faking multitex by multipass is evil...
1881 * Implementing NCC requires three stages:
1882 * fxDDChooseTextureFormat:
1883 * bind GL_COMPRESSED_RGB[A] to _mesa_texformat_argb8888,
1884 * so we can quantize properly, at a later time
1886 * if GL_COMPRESSED_RGB
1887 * use _mesa_texformat_l8 to get 1bpt and set GR_TEXFMT_YIQ_422
1888 * if GL_COMPRESSED_RGBA
1889 * use _mesa_texformat_al88 to get 2bpt and set GR_TEXFMT_AYIQ_8422
1890 * txMipQuantize(...);
1892 * txPalToNcc((GuNccTable *)(&(ti->palette)), pxMip.pal);
1894 * fxSetupSingleTMU_NoLock/fxSetupDoubleTMU_NoLock:
1895 * grTexDownloadTable(GR_TEXTABLE_NCC0, &(ti->palette));
1897 /*_mesa_enable_extension(ctx, "GL_ARB_texture_compression");*/
1898 _mesa_enable_extension(ctx
, "GL_SGIS_generate_mipmap");
1901 if (fxMesa
->HaveCmbExt
) {
1902 _mesa_enable_extension(ctx
, "GL_ARB_texture_env_combine");
1903 _mesa_enable_extension(ctx
, "GL_EXT_texture_env_combine");
1906 if (fxMesa
->HavePixExt
) {
1907 _mesa_enable_extension(ctx
, "GL_EXT_blend_subtract");
1908 _mesa_enable_extension(ctx
, "GL_EXT_blend_equation_separate");
1911 if (fxMesa
->HaveMirExt
) {
1912 _mesa_enable_extension(ctx
, "GL_ARB_texture_mirrored_repeat");
1915 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo2
) {
1916 _mesa_enable_extension(ctx
, "GL_EXT_fog_coord");
1919 /* core-level extensions */
1920 _mesa_enable_extension(ctx
, "GL_EXT_multi_draw_arrays");
1921 _mesa_enable_extension(ctx
, "GL_IBM_multimode_draw_arrays");
1922 _mesa_enable_extension(ctx
, "GL_ARB_vertex_buffer_object");
1924 if (getenv("MESA_FX_ALLOW_VP")) {
1925 _mesa_enable_extension(ctx
, "GL_ARB_vertex_program");
1926 _mesa_enable_extension(ctx
, "GL_NV_vertex_program");
1927 _mesa_enable_extension(ctx
, "GL_NV_vertex_program1_1");
1928 _mesa_enable_extension(ctx
, "GL_MESA_program_debug");
1931 /* this requires _tnl_vertex_cull_stage in the pipeline */
1932 _mesa_enable_extension(ctx
, "EXT_cull_vertex");
1937 /************************************************************************/
1938 /************************************************************************/
1939 /************************************************************************/
1941 /* Check if the hardware supports the current context
1943 * Performs similar work to fxDDChooseRenderState() - should be merged.
1946 fx_check_IsInHardware(GLcontext
* ctx
)
1948 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1950 if (ctx
->RenderMode
!= GL_RENDER
) {
1951 return FX_FALLBACK_RENDER_MODE
;
1954 if (ctx
->Stencil
.Enabled
&& !fxMesa
->haveHwStencil
) {
1955 return FX_FALLBACK_STENCIL
;
1958 if (ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] != BUFFER_BIT_FRONT_LEFT
&&
1959 ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] != BUFFER_BIT_BACK_LEFT
) {
1960 return FX_FALLBACK_DRAW_BUFFER
;
1963 if (ctx
->Color
.BlendEnabled
) {
1964 if (ctx
->Color
.BlendEquationRGB
!= GL_FUNC_ADD
) {
1965 if (!fxMesa
->HavePixExt
||
1966 ((ctx
->Color
.BlendEquationRGB
!= GL_FUNC_SUBTRACT
) &&
1967 (ctx
->Color
.BlendEquationRGB
!= GL_FUNC_REVERSE_SUBTRACT
))) {
1968 return FX_FALLBACK_BLEND
;
1972 if (ctx
->Color
.BlendEquationA
!= GL_FUNC_ADD
) {
1973 if (!fxMesa
->HavePixExt
||
1974 ((ctx
->Color
.BlendEquationA
!= GL_FUNC_SUBTRACT
) &&
1975 (ctx
->Color
.BlendEquationA
!= GL_FUNC_REVERSE_SUBTRACT
))) {
1976 return FX_FALLBACK_BLEND
;
1982 * We fail the spec here, unless certain blending modes:
1983 * RGB: (GL_ONE + GL_*) or (GL_ZERO + GL_*) or ...
1985 if (NEED_SECONDARY_COLOR(ctx
)) {
1986 if ((ctx
->Color
.BlendEquationRGB
!= GL_FUNC_ADD
) &&
1987 (ctx
->Color
.BlendSrcRGB
!= GL_ONE
)) {
1988 /* Can't use multipass to blend ColorSum stage */
1989 return FX_FALLBACK_SPECULAR
;
1996 * We could avoid this for certain `sfactor/dfactor'
1997 * I do not think that is even worthwhile to check
1998 * because if someone is using blending they use more
1999 * interesting settings and also it would add more
2000 * state tracking to a lot of the code.
2002 if (ctx
->Color
.ColorLogicOpEnabled
&& (ctx
->Color
.LogicOp
!= GL_COPY
)) {
2003 return FX_FALLBACK_LOGICOP
;
2006 if ((fxMesa
->colDepth
!= 32) &&
2007 ((ctx
->Color
.ColorMask
[RCOMP
] != ctx
->Color
.ColorMask
[GCOMP
]) ||
2008 (ctx
->Color
.ColorMask
[GCOMP
] != ctx
->Color
.ColorMask
[BCOMP
]))) {
2009 return FX_FALLBACK_COLORMASK
;
2012 /* Unsupported texture/multitexture cases */
2014 /* we can only do 1D/2D textures */
2015 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& ~(TEXTURE_1D_BIT
|TEXTURE_2D_BIT
))
2016 return FX_FALLBACK_TEXTURE_MAP
;
2018 if (fxMesa
->haveTwoTMUs
) {
2019 if (ctx
->Texture
.Unit
[1]._ReallyEnabled
& ~(TEXTURE_1D_BIT
|TEXTURE_2D_BIT
))
2020 return FX_FALLBACK_TEXTURE_MAP
;
2022 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
) {
2023 if (fxMesa
->type
< GR_SSTTYPE_Voodoo2
)
2024 if (ctx
->Texture
.Unit
[0].EnvMode
== GL_BLEND
&&
2025 (ctx
->Texture
.Unit
[1]._ReallyEnabled
||
2026 ctx
->Texture
.Unit
[0].EnvColor
[0] != 0 ||
2027 ctx
->Texture
.Unit
[0].EnvColor
[1] != 0 ||
2028 ctx
->Texture
.Unit
[0].EnvColor
[2] != 0 ||
2029 ctx
->Texture
.Unit
[0].EnvColor
[3] != 1)) {
2030 return FX_FALLBACK_TEXTURE_ENV
;
2032 if (ctx
->Texture
.Unit
[0]._Current
->Image
[0][0]->Border
> 0)
2033 return FX_FALLBACK_TEXTURE_BORDER
;
2036 if (ctx
->Texture
.Unit
[1]._ReallyEnabled
) {
2037 if (fxMesa
->type
< GR_SSTTYPE_Voodoo2
)
2038 if (ctx
->Texture
.Unit
[1].EnvMode
== GL_BLEND
)
2039 return FX_FALLBACK_TEXTURE_ENV
;
2040 if (ctx
->Texture
.Unit
[1]._Current
->Image
[0][0]->Border
> 0)
2041 return FX_FALLBACK_TEXTURE_BORDER
;
2044 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
2045 fprintf(stderr
, "fx_check_IsInHardware: envmode is %s/%s\n",
2046 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[0].EnvMode
),
2047 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[1].EnvMode
));
2049 /* KW: This was wrong (I think) and I changed it... which doesn't mean
2050 * it is now correct...
2051 * BP: The old condition just seemed to test if both texture units
2052 * were enabled. That's easy!
2054 if (ctx
->Texture
._EnabledUnits
== 0x3) {
2056 /* Can't use multipass to blend a multitextured triangle - fall
2059 if (!fxMesa
->haveTwoTMUs
&& ctx
->Color
.BlendEnabled
) {
2060 return FX_FALLBACK_TEXTURE_MULTI
;
2064 if (!fxMesa
->HaveCmbExt
&&
2065 (ctx
->Texture
.Unit
[0].EnvMode
!= ctx
->Texture
.Unit
[1].EnvMode
) &&
2066 (ctx
->Texture
.Unit
[0].EnvMode
!= GL_MODULATE
) &&
2067 (ctx
->Texture
.Unit
[0].EnvMode
!= GL_REPLACE
)) { /* q2, seems ok... */
2068 if (TDFX_DEBUG
& VERBOSE_DRIVER
)
2069 fprintf(stderr
, "fx_check_IsInHardware: unsupported multitex env mode\n");
2070 return FX_FALLBACK_TEXTURE_MULTI
;
2075 /* we have just one texture unit */
2076 if (ctx
->Texture
._EnabledUnits
> 0x1) {
2077 return FX_FALLBACK_TEXTURE_MULTI
;
2080 if (fxMesa
->type
< GR_SSTTYPE_Voodoo2
)
2081 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
&&
2082 (ctx
->Texture
.Unit
[0].EnvMode
== GL_BLEND
)) {
2083 return FX_FALLBACK_TEXTURE_ENV
;
2093 fxDDUpdateDDPointers(GLcontext
* ctx
, GLuint new_state
)
2095 /* TNLcontext *tnl = TNL_CONTEXT(ctx); */
2096 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2098 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
2099 fprintf(stderr
, "fxDDUpdateDDPointers(%08x)\n", new_state
);
2102 _swrast_InvalidateState(ctx
, new_state
);
2103 _vbo_InvalidateState(ctx
, new_state
);
2104 _tnl_InvalidateState(ctx
, new_state
);
2105 _swsetup_InvalidateState(ctx
, new_state
);
2107 fxMesa
->new_gl_state
|= new_state
;
2114 fxSetupDDPointers(GLcontext
* ctx
)
2116 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2117 /* TNLcontext *tnl = TNL_CONTEXT(ctx); */
2119 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
2120 fprintf(stderr
, "fxSetupDDPointers()\n");
2123 ctx
->Driver
.UpdateState
= fxDDUpdateDDPointers
;
2124 ctx
->Driver
.GetString
= fxDDGetString
;
2125 ctx
->Driver
.ClearIndex
= NULL
;
2126 ctx
->Driver
.ClearColor
= fxDDClearColor
;
2127 ctx
->Driver
.Clear
= fxDDClear
;
2128 ctx
->Driver
.DrawBuffer
= fxDDSetDrawBuffer
;
2129 ctx
->Driver
.GetBufferSize
= fxDDGetBufferSize
;
2130 ctx
->Driver
.Viewport
= fxDDViewport
;
2131 switch (fxMesa
->colDepth
) {
2133 ctx
->Driver
.DrawPixels
= fxDDDrawPixels555
;
2134 ctx
->Driver
.ReadPixels
= fxDDReadPixels555
;
2135 ctx
->Driver
.Bitmap
= fxDDDrawBitmap2
;
2138 ctx
->Driver
.DrawPixels
= !fxMesa
->bgrOrder
? fxDDDrawPixels565
: fxDDDrawPixels565_rev
;
2139 ctx
->Driver
.ReadPixels
= fxDDReadPixels565
;
2140 ctx
->Driver
.Bitmap
= fxDDDrawBitmap2
;
2143 ctx
->Driver
.DrawPixels
= fxDDDrawPixels8888
;
2144 ctx
->Driver
.ReadPixels
= fxDDReadPixels8888
;
2145 ctx
->Driver
.Bitmap
= fxDDDrawBitmap4
;
2148 ctx
->Driver
.Finish
= fxDDFinish
;
2149 ctx
->Driver
.Flush
= NULL
;
2150 ctx
->Driver
.ChooseTextureFormat
= fxDDChooseTextureFormat
;
2151 ctx
->Driver
.TexImage1D
= fxDDTexImage1D
;
2152 ctx
->Driver
.TexImage2D
= fxDDTexImage2D
;
2153 ctx
->Driver
.TexSubImage1D
= fxDDTexSubImage1D
;
2154 ctx
->Driver
.TexSubImage2D
= fxDDTexSubImage2D
;
2155 ctx
->Driver
.CompressedTexImage2D
= fxDDCompressedTexImage2D
;
2156 ctx
->Driver
.CompressedTexSubImage2D
= fxDDCompressedTexSubImage2D
;
2157 ctx
->Driver
.TestProxyTexImage
= fxDDTestProxyTexImage
;
2158 ctx
->Driver
.TexEnv
= fxDDTexEnv
;
2159 ctx
->Driver
.TexParameter
= fxDDTexParam
;
2160 ctx
->Driver
.BindTexture
= fxDDTexBind
;
2161 ctx
->Driver
.DeleteTexture
= fxDDTexDel
;
2162 ctx
->Driver
.IsTextureResident
= fxDDIsTextureResident
;
2163 ctx
->Driver
.UpdateTexturePalette
= fxDDTexPalette
;
2164 ctx
->Driver
.AlphaFunc
= fxDDAlphaFunc
;
2165 ctx
->Driver
.BlendFuncSeparate
= fxDDBlendFuncSeparate
;
2166 ctx
->Driver
.BlendEquationSeparate
= fxDDBlendEquationSeparate
;
2167 ctx
->Driver
.DepthFunc
= fxDDDepthFunc
;
2168 ctx
->Driver
.DepthMask
= fxDDDepthMask
;
2169 ctx
->Driver
.ColorMask
= fxDDColorMask
;
2170 ctx
->Driver
.Fogfv
= fxDDFogfv
;
2171 ctx
->Driver
.Scissor
= fxDDScissor
;
2172 ctx
->Driver
.FrontFace
= fxDDFrontFace
;
2173 ctx
->Driver
.CullFace
= fxDDCullFace
;
2174 ctx
->Driver
.ShadeModel
= fxDDShadeModel
;
2175 ctx
->Driver
.Enable
= fxDDEnable
;
2176 if (fxMesa
->haveHwStencil
) {
2177 ctx
->Driver
.StencilFuncSeparate
= fxDDStencilFuncSeparate
;
2178 ctx
->Driver
.StencilMaskSeparate
= fxDDStencilMaskSeparate
;
2179 ctx
->Driver
.StencilOpSeparate
= fxDDStencilOpSeparate
;
2182 fxSetupDDSpanPointers(ctx
);
2183 fxDDUpdateDDPointers(ctx
, ~0);
2191 * Need this to provide at least one external definition.
2194 extern int gl_fx_dummy_function_dd(void);
2196 gl_fx_dummy_function_dd(void)