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"
58 #include "array_cache/acache.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 fxDDViewport(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
129 /* poll for window size change and realloc software Z/stencil/etc if needed */
130 _mesa_ResizeBuffersMESA();
134 /* Implements glClearColor() */
136 fxDDClearColor(GLcontext
* ctx
, const GLfloat color
[4])
138 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
141 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
142 fprintf(stderr
, "fxDDClearColor(%f, %f, %f, %f)\n",
143 color
[0], color
[1], color
[2], color
[3]);
146 CLAMPED_FLOAT_TO_UBYTE(col
[0], color
[0]);
147 CLAMPED_FLOAT_TO_UBYTE(col
[1], color
[1]);
148 CLAMPED_FLOAT_TO_UBYTE(col
[2], color
[2]);
149 CLAMPED_FLOAT_TO_UBYTE(col
[3], color
[3]);
151 fxMesa
->clearC
= FXCOLOR4(col
);
152 fxMesa
->clearA
= col
[3];
156 /* Clear the color and/or depth buffers */
157 static void fxDDClear( GLcontext
*ctx
,
158 GLbitfield mask
, GLboolean all
,
159 GLint x
, GLint y
, GLint width
, GLint height
)
161 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
162 GLbitfield softwareMask
= mask
& (BUFFER_BIT_ACCUM
);
163 const GLuint stencil_size
= fxMesa
->haveHwStencil
? ctx
->Visual
.stencilBits
: 0;
164 const FxU32 clearD
= (FxU32
) (ctx
->DrawBuffer
->_DepthMaxF
* ctx
->Depth
.Clear
);
165 const FxU8 clearS
= (FxU8
) (ctx
->Stencil
.Clear
& 0xff);
167 if ( TDFX_DEBUG
& MESA_VERBOSE
) {
168 fprintf( stderr
, "fxDDClear( %d, %d, %d, %d )\n",
169 (int) x
, (int) y
, (int) width
, (int) height
);
172 /* we can't clear accum buffers nor stereo */
173 mask
&= ~(BUFFER_BIT_ACCUM
| BUFFER_BIT_FRONT_RIGHT
| BUFFER_BIT_BACK_RIGHT
);
175 /* Need this check to respond to certain HW updates */
176 if (fxMesa
->new_state
& (FX_NEW_SCISSOR
| FX_NEW_COLOR_MASK
)) {
178 fxSetupColorMask(ctx
);
179 fxMesa
->new_state
&= ~(FX_NEW_SCISSOR
| FX_NEW_COLOR_MASK
);
183 * As per GL spec, color masking should be obeyed when clearing
185 if (ctx
->Visual
.greenBits
!= 8) {
186 /* can only do color masking if running in 24/32bpp on Napalm */
187 if (ctx
->Color
.ColorMask
[RCOMP
] != ctx
->Color
.ColorMask
[GCOMP
] ||
188 ctx
->Color
.ColorMask
[GCOMP
] != ctx
->Color
.ColorMask
[BCOMP
]) {
189 softwareMask
|= (mask
& (BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
));
190 mask
&= ~(BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
);
194 if (fxMesa
->haveHwStencil
) {
196 * If we want to clear stencil, it must be enabled
197 * in the HW, even if the stencil test is not enabled
201 if (mask
& BUFFER_BIT_STENCIL
) {
202 fxMesa
->Glide
.grStencilMaskExt(fxMesa
->unitsState
.stencilWriteMask
);
203 /* set stencil ref value = desired clear value */
204 fxMesa
->Glide
.grStencilFuncExt(GR_CMP_ALWAYS
, clearS
, 0xff);
205 fxMesa
->Glide
.grStencilOpExt(GR_STENCILOP_REPLACE
,
206 GR_STENCILOP_REPLACE
, GR_STENCILOP_REPLACE
);
207 grEnable(GR_STENCIL_MODE_EXT
);
210 grDisable(GR_STENCIL_MODE_EXT
);
213 } else if (mask
& BUFFER_BIT_STENCIL
) {
214 softwareMask
|= (mask
& (BUFFER_BIT_STENCIL
));
215 mask
&= ~(BUFFER_BIT_STENCIL
);
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
& ~BUFFER_BIT_STENCIL
) {
229 case BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_DEPTH
:
230 /* back buffer & depth */
232 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
233 if (stencil_size
> 0) {
234 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
239 grBufferClear(fxMesa
->clearC
,
243 case BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_DEPTH
:
244 /* XXX it appears that the depth buffer isn't cleared when
245 * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
246 * This is a work-around/
250 fxDisableColor(fxMesa
);
251 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
252 if (stencil_size
> 0)
253 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
257 grBufferClear(fxMesa
->clearC
,
260 fxSetupColorMask(ctx
);
261 grDepthMask(FXFALSE
);
263 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
264 if (stencil_size
> 0)
265 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
269 grBufferClear(fxMesa
->clearC
,
273 case BUFFER_BIT_BACK_LEFT
:
274 /* back buffer only */
275 grDepthMask(FXFALSE
);
276 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
277 if (stencil_size
> 0)
278 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
282 grBufferClear(fxMesa
->clearC
,
286 case BUFFER_BIT_FRONT_LEFT
:
287 /* front buffer only */
288 grDepthMask(FXFALSE
);
289 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
290 if (stencil_size
> 0)
291 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
295 grBufferClear(fxMesa
->clearC
,
299 case BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
:
301 grDepthMask(FXFALSE
);
302 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
303 if (stencil_size
> 0)
304 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
308 grBufferClear(fxMesa
->clearC
,
311 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
312 if (stencil_size
> 0)
313 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
317 grBufferClear(fxMesa
->clearC
,
321 case BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_DEPTH
:
322 /* clear back and depth */
324 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
325 if (stencil_size
> 0)
326 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
330 grBufferClear(fxMesa
->clearC
,
334 grDepthMask(FXFALSE
);
335 grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
336 if (stencil_size
> 0)
337 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
341 grBufferClear(fxMesa
->clearC
,
345 case BUFFER_BIT_DEPTH
:
346 /* just the depth buffer */
348 fxDisableColor(fxMesa
);
349 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
350 if (stencil_size
> 0)
351 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
355 grBufferClear(fxMesa
->clearC
,
358 fxSetupColorMask(ctx
);
361 /* clear no color buffers or depth buffer but might clear stencil */
362 if ((stencil_size
> 0) && (mask
& BUFFER_BIT_STENCIL
)) {
363 /* XXX need this RenderBuffer call to work around Glide bug */
364 grDepthMask(FXFALSE
);
365 grRenderBuffer(GR_BUFFER_BACKBUFFER
);
366 fxDisableColor(fxMesa
);
367 fxMesa
->Glide
.grBufferClearExt(fxMesa
->clearC
,
370 fxSetupColorMask(ctx
);
376 if (fxMesa
->haveHwStencil
) {
377 /* We changed the stencil state above. Restore it! */
380 fxSetupDepthTest(ctx
);
381 grRenderBuffer(fxMesa
->currentFB
);
384 _swrast_Clear( ctx
, softwareMask
, all
, x
, y
, width
, height
);
388 /* Set the buffer used for drawing */
389 /* XXX support for separate read/draw buffers hasn't been tested */
390 /* XXX GL_NONE disables color, but fails to correctly maintain state */
392 fxDDSetDrawBuffer(GLcontext
* ctx
, GLenum mode
)
394 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
396 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
397 fprintf(stderr
, "fxDDSetDrawBuffer(%x)\n", (int)mode
);
400 if (mode
== GL_FRONT_LEFT
) {
401 fxMesa
->currentFB
= GR_BUFFER_FRONTBUFFER
;
402 grRenderBuffer(fxMesa
->currentFB
);
404 else if (mode
== GL_BACK_LEFT
) {
405 fxMesa
->currentFB
= GR_BUFFER_BACKBUFFER
;
406 grRenderBuffer(fxMesa
->currentFB
);
408 else if (mode
== GL_NONE
) {
409 fxDisableColor(fxMesa
);
412 /* we'll need a software fallback */
413 /* XXX not implemented */
416 /* update s/w fallback state */
417 _swrast_DrawBuffer(ctx
, mode
);
422 fxDDDrawBitmap2 (GLcontext
*ctx
, GLint px
, GLint py
,
423 GLsizei width
, GLsizei height
,
424 const struct gl_pixelstore_attrib
*unpack
,
425 const GLubyte
*bitmap
)
427 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
428 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
430 GrLfbWriteMode_t mode
;
432 const struct gl_pixelstore_attrib
*finalUnpack
;
433 struct gl_pixelstore_attrib scissoredUnpack
;
435 /* check if there's any raster operations enabled which we can't handle */
436 if (swrast
->_RasterMask
& (ALPHATEST_BIT
|
437 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
438 DEPTH_BIT
| /* could be done with RGB:DEPTH */
439 FOG_BIT
| /* could be done with RGB:DEPTH */
441 /*CLIP_BIT |*/ /* clipping ok, below */
445 OCCLUSION_BIT
| /* nope! at least not yet */
448 _swrast_Bitmap(ctx
, px
, py
, width
, height
, unpack
, bitmap
);
452 /* make sure the pixelpipe is configured correctly */
455 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
456 if (ctx
->Scissor
.Enabled
) {
457 /* This is a bit tricky, but by carefully adjusting the px, py,
458 * width, height, skipPixels and skipRows values we can do
459 * scissoring without special code in the rendering loop.
462 /* we'll construct a new pixelstore struct */
463 finalUnpack
= &scissoredUnpack
;
464 scissoredUnpack
= *unpack
;
465 if (scissoredUnpack
.RowLength
== 0)
466 scissoredUnpack
.RowLength
= width
;
469 if (px
< ctx
->Scissor
.X
) {
470 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- px
);
471 width
-= (ctx
->Scissor
.X
- px
);
475 if (px
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
476 width
-= (px
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
479 if (py
< ctx
->Scissor
.Y
) {
480 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- py
);
481 height
-= (ctx
->Scissor
.Y
- py
);
485 if (py
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
486 height
-= (py
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
489 if (width
<= 0 || height
<= 0)
493 finalUnpack
= unpack
;
496 /* compute pixel value */
498 GLint r
= (GLint
) (ctx
->Current
.RasterColor
[RCOMP
] * 255.0f
);
499 GLint g
= (GLint
) (ctx
->Current
.RasterColor
[GCOMP
] * 255.0f
);
500 GLint b
= (GLint
) (ctx
->Current
.RasterColor
[BCOMP
] * 255.0f
);
501 GLint a
= (GLint
) (ctx
->Current
.RasterColor
[ACOMP
] * 255.0f
);
502 if (fxMesa
->colDepth
== 15) {
503 color
= TDFXPACKCOLOR1555(b
, g
, r
, a
);
504 mode
= GR_LFBWRITEMODE_1555
;
506 color
= fxMesa
->bgrOrder
? TDFXPACKCOLOR565(r
, g
, b
) : TDFXPACKCOLOR565(b
, g
, r
);
507 mode
= GR_LFBWRITEMODE_565
;
511 info
.size
= sizeof(info
);
512 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
515 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
516 _swrast_Bitmap(ctx
, px
, py
, width
, height
, finalUnpack
, bitmap
);
521 const GLint winX
= 0;
522 const GLint winY
= 0;
523 /* The dest stride depends on the hardware and whether we're drawing
524 * to the front or back buffer. This compile-time test seems to do
527 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
530 /* compute dest address of bottom-left pixel in bitmap */
531 GLushort
*dst
= (GLushort
*) info
.lfbPtr
532 + (winY
+ py
) * dstStride
+ (winX
+ px
);
534 for (row
= 0; row
< height
; row
++) {
536 (const GLubyte
*) _mesa_image_address2d(finalUnpack
,
537 bitmap
, width
, height
,
538 GL_COLOR_INDEX
, GL_BITMAP
,
540 if (finalUnpack
->LsbFirst
) {
541 /* least significan bit first */
542 GLubyte mask
= 1U << (finalUnpack
->SkipPixels
& 0x7);
544 for (col
= 0; col
< width
; col
++) {
560 /* most significan bit first */
561 GLubyte mask
= 128U >> (finalUnpack
->SkipPixels
& 0x7);
563 for (col
= 0; col
< width
; col
++) {
582 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
586 fxDDDrawBitmap4 (GLcontext
*ctx
, GLint px
, GLint py
,
587 GLsizei width
, GLsizei height
,
588 const struct gl_pixelstore_attrib
*unpack
,
589 const GLubyte
*bitmap
)
591 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
592 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
595 const struct gl_pixelstore_attrib
*finalUnpack
;
596 struct gl_pixelstore_attrib scissoredUnpack
;
598 /* check if there's any raster operations enabled which we can't handle */
599 if ((swrast
->_RasterMask
& (/*ALPHATEST_BIT |*/
600 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
601 DEPTH_BIT
| /* could be done with RGB:DEPTH */
602 FOG_BIT
| /* could be done with RGB:DEPTH */
604 /*CLIP_BIT |*/ /* clipping ok, below */
606 /*MASKING_BIT |*/ /* masking ok, we're in 32bpp */
608 OCCLUSION_BIT
| /* nope! at least not yet */
612 _swrast_Bitmap(ctx
, px
, py
, width
, height
, unpack
, bitmap
);
616 /* make sure the pixelpipe is configured correctly */
619 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
620 if (ctx
->Scissor
.Enabled
) {
621 /* This is a bit tricky, but by carefully adjusting the px, py,
622 * width, height, skipPixels and skipRows values we can do
623 * scissoring without special code in the rendering loop.
626 /* we'll construct a new pixelstore struct */
627 finalUnpack
= &scissoredUnpack
;
628 scissoredUnpack
= *unpack
;
629 if (scissoredUnpack
.RowLength
== 0)
630 scissoredUnpack
.RowLength
= width
;
633 if (px
< ctx
->Scissor
.X
) {
634 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- px
);
635 width
-= (ctx
->Scissor
.X
- px
);
639 if (px
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
640 width
-= (px
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
643 if (py
< ctx
->Scissor
.Y
) {
644 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- py
);
645 height
-= (ctx
->Scissor
.Y
- py
);
649 if (py
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
650 height
-= (py
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
653 if (width
<= 0 || height
<= 0)
657 finalUnpack
= unpack
;
660 /* compute pixel value */
662 GLint r
= (GLint
) (ctx
->Current
.RasterColor
[RCOMP
] * 255.0f
);
663 GLint g
= (GLint
) (ctx
->Current
.RasterColor
[GCOMP
] * 255.0f
);
664 GLint b
= (GLint
) (ctx
->Current
.RasterColor
[BCOMP
] * 255.0f
);
665 GLint a
= (GLint
) (ctx
->Current
.RasterColor
[ACOMP
] * 255.0f
);
666 color
= TDFXPACKCOLOR8888(b
, g
, r
, a
);
669 info
.size
= sizeof(info
);
670 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
672 GR_LFBWRITEMODE_8888
,
673 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
674 _swrast_Bitmap(ctx
, px
, py
, width
, height
, finalUnpack
, bitmap
);
679 const GLint winX
= 0;
680 const GLint winY
= 0;
681 /* The dest stride depends on the hardware and whether we're drawing
682 * to the front or back buffer. This compile-time test seems to do
685 const GLint dstStride
= info
.strideInBytes
/ 4; /* stride in GLuints */
688 /* compute dest address of bottom-left pixel in bitmap */
689 GLuint
*dst
= (GLuint
*) info
.lfbPtr
690 + (winY
+ py
) * dstStride
+ (winX
+ px
);
692 for (row
= 0; row
< height
; row
++) {
694 (const GLubyte
*) _mesa_image_address2d(finalUnpack
,
695 bitmap
, width
, height
,
696 GL_COLOR_INDEX
, GL_BITMAP
,
698 if (finalUnpack
->LsbFirst
) {
699 /* least significan bit first */
700 GLubyte mask
= 1U << (finalUnpack
->SkipPixels
& 0x7);
702 for (col
= 0; col
< width
; col
++) {
718 /* most significan bit first */
719 GLubyte mask
= 128U >> (finalUnpack
->SkipPixels
& 0x7);
721 for (col
= 0; col
< width
; col
++) {
740 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
745 fxDDReadPixels565 (GLcontext
* ctx
,
747 GLsizei width
, GLsizei height
,
748 GLenum format
, GLenum type
,
749 const struct gl_pixelstore_attrib
*packing
,
752 if (ctx
->_ImageTransferState
/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) {
753 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
758 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
762 info
.size
= sizeof(info
);
763 if (grLfbLock(GR_LFB_READ_ONLY
,
766 GR_ORIGIN_UPPER_LEFT
, FXFALSE
, &info
)) {
767 const GLint winX
= 0;
768 const GLint winY
= fxMesa
->height
- 1;
769 const GLint srcStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
770 const GLushort
*src
= (const GLushort
*) info
.lfbPtr
771 + (winY
- y
) * srcStride
+ (winX
+ x
);
772 GLubyte
*dst
= (GLubyte
*) _mesa_image_address2d(packing
, dstImage
,
773 width
, height
, format
,
776 _mesa_image_row_stride(packing
, width
, format
, type
);
778 if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
779 /* convert 5R6G5B into 8R8G8B */
781 const GLint halfWidth
= width
>> 1;
782 const GLint extraPixel
= (width
& 1);
783 for (row
= 0; row
< height
; row
++) {
785 for (col
= 0; col
< halfWidth
; col
++) {
786 const GLuint pixel
= ((const GLuint
*) src
)[col
];
787 *d
++ = FX_rgb_scale_5
[(pixel
>> 11) & 0x1f];
788 *d
++ = FX_rgb_scale_6
[(pixel
>> 5) & 0x3f];
789 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
790 *d
++ = FX_rgb_scale_5
[(pixel
>> 27) & 0x1f];
791 *d
++ = FX_rgb_scale_6
[(pixel
>> 21) & 0x3f];
792 *d
++ = FX_rgb_scale_5
[(pixel
>> 16) & 0x1f];
795 GLushort pixel
= src
[width
- 1];
796 *d
++ = FX_rgb_scale_5
[(pixel
>> 11) & 0x1f];
797 *d
++ = FX_rgb_scale_6
[(pixel
>> 5) & 0x3f];
798 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
804 else if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
805 /* convert 5R6G5B into 8R8G8B8A */
807 const GLint halfWidth
= width
>> 1;
808 const GLint extraPixel
= (width
& 1);
809 for (row
= 0; row
< height
; row
++) {
811 for (col
= 0; col
< halfWidth
; col
++) {
812 const GLuint pixel
= ((const GLuint
*) src
)[col
];
813 *d
++ = FX_rgb_scale_5
[(pixel
>> 11) & 0x1f];
814 *d
++ = FX_rgb_scale_6
[(pixel
>> 5) & 0x3f];
815 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
817 *d
++ = FX_rgb_scale_5
[(pixel
>> 27) & 0x1f];
818 *d
++ = FX_rgb_scale_6
[(pixel
>> 21) & 0x3f];
819 *d
++ = FX_rgb_scale_5
[(pixel
>> 16) & 0x1f];
823 const GLushort pixel
= src
[width
- 1];
824 *d
++ = FX_rgb_scale_5
[(pixel
>> 11) & 0x1f];
825 *d
++ = FX_rgb_scale_6
[(pixel
>> 5) & 0x3f];
826 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
833 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
834 /* directly memcpy 5R6G5B pixels into client's buffer */
835 const GLint widthInBytes
= width
* 2;
837 for (row
= 0; row
< height
; row
++) {
838 MEMCPY(dst
, src
, widthInBytes
);
844 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
846 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
851 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
858 fxDDReadPixels555 (GLcontext
* ctx
,
860 GLsizei width
, GLsizei height
,
861 GLenum format
, GLenum type
,
862 const struct gl_pixelstore_attrib
*packing
,
865 if (ctx
->_ImageTransferState
/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) {
866 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
871 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
875 info
.size
= sizeof(info
);
876 if (grLfbLock(GR_LFB_READ_ONLY
,
879 GR_ORIGIN_UPPER_LEFT
, FXFALSE
, &info
)) {
880 const GLint winX
= 0;
881 const GLint winY
= fxMesa
->height
- 1;
882 const GLint srcStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
883 const GLushort
*src
= (const GLushort
*) info
.lfbPtr
884 + (winY
- y
) * srcStride
+ (winX
+ x
);
885 GLubyte
*dst
= (GLubyte
*) _mesa_image_address2d(packing
, dstImage
,
886 width
, height
, format
,
889 _mesa_image_row_stride(packing
, width
, format
, type
);
891 if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
892 /* convert 5R5G5B into 8R8G8B */
894 const GLint halfWidth
= width
>> 1;
895 const GLint extraPixel
= (width
& 1);
896 for (row
= 0; row
< height
; row
++) {
898 for (col
= 0; col
< halfWidth
; col
++) {
899 const GLuint pixel
= ((const GLuint
*) src
)[col
];
900 *d
++ = FX_rgb_scale_5
[(pixel
>> 10) & 0x1f];
901 *d
++ = FX_rgb_scale_5
[(pixel
>> 5) & 0x1f];
902 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
903 *d
++ = FX_rgb_scale_5
[(pixel
>> 26) & 0x1f];
904 *d
++ = FX_rgb_scale_5
[(pixel
>> 21) & 0x1f];
905 *d
++ = FX_rgb_scale_5
[(pixel
>> 16) & 0x1f];
908 GLushort pixel
= src
[width
- 1];
909 *d
++ = FX_rgb_scale_5
[(pixel
>> 10) & 0x1f];
910 *d
++ = FX_rgb_scale_5
[(pixel
>> 5) & 0x1f];
911 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
917 else if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
918 /* convert 5R6G5B into 8R8G8B8A */
920 const GLint halfWidth
= width
>> 1;
921 const GLint extraPixel
= (width
& 1);
922 for (row
= 0; row
< height
; row
++) {
924 for (col
= 0; col
< halfWidth
; col
++) {
925 const GLuint pixel
= ((const GLuint
*) src
)[col
];
926 *d
++ = FX_rgb_scale_5
[(pixel
>> 10) & 0x1f];
927 *d
++ = FX_rgb_scale_5
[(pixel
>> 5) & 0x1f];
928 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
929 *d
++ = (pixel
& 0x8000) ? 255 : 0;
930 *d
++ = FX_rgb_scale_5
[(pixel
>> 26) & 0x1f];
931 *d
++ = FX_rgb_scale_5
[(pixel
>> 21) & 0x1f];
932 *d
++ = FX_rgb_scale_5
[(pixel
>> 16) & 0x1f];
933 *d
++ = (pixel
& 0x80000000) ? 255 : 0;
936 const GLushort pixel
= src
[width
- 1];
937 *d
++ = FX_rgb_scale_5
[(pixel
>> 10) & 0x1f];
938 *d
++ = FX_rgb_scale_5
[(pixel
>> 5) & 0x1f];
939 *d
++ = FX_rgb_scale_5
[ pixel
& 0x1f];
940 *d
++ = (pixel
& 0x8000) ? 255 : 0;
946 else if (format
== GL_BGRA
&& type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
947 /* directly memcpy 5R5G5B pixels into client's buffer */
948 const GLint widthInBytes
= width
* 2;
950 for (row
= 0; row
< height
; row
++) {
951 MEMCPY(dst
, src
, widthInBytes
);
957 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
959 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
964 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
971 fxDDReadPixels8888 (GLcontext
* ctx
,
973 GLsizei width
, GLsizei height
,
974 GLenum format
, GLenum type
,
975 const struct gl_pixelstore_attrib
*packing
,
978 if (ctx
->_ImageTransferState
/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) {
979 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
984 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
988 info
.size
= sizeof(info
);
989 if (grLfbLock(GR_LFB_READ_ONLY
,
992 GR_ORIGIN_UPPER_LEFT
, FXFALSE
, &info
)) {
993 const GLint winX
= 0;
994 const GLint winY
= fxMesa
->height
- 1;
995 const GLint srcStride
= info
.strideInBytes
/ 4; /* stride in GLuints */
996 const GLuint
*src
= (const GLuint
*) info
.lfbPtr
997 + (winY
- y
) * srcStride
+ (winX
+ x
);
998 GLubyte
*dst
= (GLubyte
*) _mesa_image_address2d(packing
, dstImage
,
999 width
, height
, format
,
1002 _mesa_image_row_stride(packing
, width
, format
, type
);
1004 if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1005 /* convert 8A8R8G8B into 8R8G8B */
1007 for (row
= 0; row
< height
; row
++) {
1009 for (col
= 0; col
< width
; col
++) {
1010 const GLuint pixel
= ((const GLuint
*) src
)[col
];
1019 else if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1020 /* 8A8R8G8B pixels into client's buffer */
1022 for (row
= 0; row
< height
; row
++) {
1024 for (col
= 0; col
< width
; col
++) {
1025 const GLuint pixel
= ((const GLuint
*) src
)[col
];
1035 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
1036 /* convert 8A8R8G8B into 5R6G5B */
1038 for (row
= 0; row
< height
; row
++) {
1039 GLushort
*d
= (GLushort
*)dst
;
1040 for (col
= 0; col
< width
; col
++) {
1041 const GLuint pixel
= ((const GLuint
*) src
)[col
];
1042 *d
++ = (((pixel
>> 16) & 0xf8) << 8) |
1043 (((pixel
>> 8) & 0xfc) << 3) |
1044 ((pixel
& 0xf8) >> 3);
1051 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
1053 _swrast_ReadPixels(ctx
, x
, y
, width
, height
, format
, type
,
1058 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
1066 fxDDDrawPixels555 (GLcontext
* ctx
, GLint x
, GLint y
,
1067 GLsizei width
, GLsizei height
,
1068 GLenum format
, GLenum type
,
1069 const struct gl_pixelstore_attrib
*unpack
,
1070 const GLvoid
* pixels
)
1072 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1073 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1075 const struct gl_pixelstore_attrib
*finalUnpack
;
1076 struct gl_pixelstore_attrib scissoredUnpack
;
1078 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
1079 ctx
->Pixel
.ZoomY
!= 1.0F
||
1080 (ctx
->_ImageTransferState
& (IMAGE_SCALE_BIAS_BIT
|
1081 IMAGE_MAP_COLOR_BIT
)) ||
1082 (swrast
->_RasterMask
& (ALPHATEST_BIT
|
1083 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
1084 DEPTH_BIT
| /* could be done with RGB:DEPTH */
1085 FOG_BIT
| /* could be done with RGB:DEPTH */
1087 /*CLIP_BIT |*/ /* clipping ok, below */
1091 OCCLUSION_BIT
| /* nope! at least not yet */
1096 _swrast_DrawPixels( ctx
, x
, y
, width
, height
, format
, type
,
1101 /* make sure the pixelpipe is configured correctly */
1102 fxSetupFXUnits(ctx
);
1104 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
1105 if (ctx
->Scissor
.Enabled
) {
1106 /* This is a bit tricky, but by carefully adjusting the px, py,
1107 * width, height, skipPixels and skipRows values we can do
1108 * scissoring without special code in the rendering loop.
1111 /* we'll construct a new pixelstore struct */
1112 finalUnpack
= &scissoredUnpack
;
1113 scissoredUnpack
= *unpack
;
1114 if (scissoredUnpack
.RowLength
== 0)
1115 scissoredUnpack
.RowLength
= width
;
1118 if (x
< ctx
->Scissor
.X
) {
1119 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- x
);
1120 width
-= (ctx
->Scissor
.X
- x
);
1124 if (x
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
1125 width
-= (x
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
1128 if (y
< ctx
->Scissor
.Y
) {
1129 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- y
);
1130 height
-= (ctx
->Scissor
.Y
- y
);
1134 if (y
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
1135 height
-= (y
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
1138 if (width
<= 0 || height
<= 0)
1142 finalUnpack
= unpack
;
1145 info
.size
= sizeof(info
);
1146 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
1148 GR_LFBWRITEMODE_1555
,
1149 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
1150 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1155 const GLint winX
= 0;
1156 const GLint winY
= 0;
1158 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
1159 GLushort
*dst
= (GLushort
*) info
.lfbPtr
+ (winY
+ y
) * dstStride
+ (winX
+ x
);
1161 if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1163 for (row
= 0; row
< height
; row
++) {
1164 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1165 pixels
, width
, height
, format
, type
, row
, 0);
1167 for (col
= 0; col
< width
; col
++) {
1168 dst
[col
] = TDFXPACKCOLOR1555(src
[2], src
[1], src
[0], src
[3]);
1174 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1176 for (row
= 0; row
< height
; row
++) {
1177 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1178 pixels
, width
, height
, format
, type
, row
, 0);
1180 for (col
= 0; col
< width
; col
++) {
1181 dst
[col
] = TDFXPACKCOLOR1555(src
[2], src
[1], src
[0], 255);
1188 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1189 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1195 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1200 fxDDDrawPixels565 (GLcontext
* ctx
, GLint x
, GLint y
,
1201 GLsizei width
, GLsizei height
,
1202 GLenum format
, GLenum type
,
1203 const struct gl_pixelstore_attrib
*unpack
,
1204 const GLvoid
* pixels
)
1206 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1207 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1209 const struct gl_pixelstore_attrib
*finalUnpack
;
1210 struct gl_pixelstore_attrib scissoredUnpack
;
1212 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
1213 ctx
->Pixel
.ZoomY
!= 1.0F
||
1214 (ctx
->_ImageTransferState
& (IMAGE_SCALE_BIAS_BIT
|
1215 IMAGE_MAP_COLOR_BIT
)) ||
1216 (swrast
->_RasterMask
& (ALPHATEST_BIT
|
1217 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
1218 DEPTH_BIT
| /* could be done with RGB:DEPTH */
1219 FOG_BIT
| /* could be done with RGB:DEPTH */
1221 /*CLIP_BIT |*/ /* clipping ok, below */
1225 OCCLUSION_BIT
| /* nope! at least not yet */
1230 _swrast_DrawPixels( ctx
, x
, y
, width
, height
, format
, type
,
1235 /* make sure the pixelpipe is configured correctly */
1236 fxSetupFXUnits(ctx
);
1238 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
1239 if (ctx
->Scissor
.Enabled
) {
1240 /* This is a bit tricky, but by carefully adjusting the px, py,
1241 * width, height, skipPixels and skipRows values we can do
1242 * scissoring without special code in the rendering loop.
1245 /* we'll construct a new pixelstore struct */
1246 finalUnpack
= &scissoredUnpack
;
1247 scissoredUnpack
= *unpack
;
1248 if (scissoredUnpack
.RowLength
== 0)
1249 scissoredUnpack
.RowLength
= width
;
1252 if (x
< ctx
->Scissor
.X
) {
1253 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- x
);
1254 width
-= (ctx
->Scissor
.X
- x
);
1258 if (x
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
1259 width
-= (x
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
1262 if (y
< ctx
->Scissor
.Y
) {
1263 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- y
);
1264 height
-= (ctx
->Scissor
.Y
- y
);
1268 if (y
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
1269 height
-= (y
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
1272 if (width
<= 0 || height
<= 0)
1276 finalUnpack
= unpack
;
1279 info
.size
= sizeof(info
);
1280 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
1282 GR_LFBWRITEMODE_565
,
1283 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
1284 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1289 const GLint winX
= 0;
1290 const GLint winY
= 0;
1292 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
1293 GLushort
*dst
= (GLushort
*) info
.lfbPtr
+ (winY
+ y
) * dstStride
+ (winX
+ x
);
1295 if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1297 for (row
= 0; row
< height
; row
++) {
1298 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1299 pixels
, width
, height
, format
, type
, row
, 0);
1301 for (col
= 0; col
< width
; col
++) {
1302 dst
[col
] = TDFXPACKCOLOR565(src
[2], src
[1], src
[0]);
1308 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1310 for (row
= 0; row
< height
; row
++) {
1311 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1312 pixels
, width
, height
, format
, type
, row
, 0);
1314 for (col
= 0; col
< width
; col
++) {
1315 dst
[col
] = TDFXPACKCOLOR565(src
[2], src
[1], src
[0]);
1322 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1323 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1329 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1334 fxDDDrawPixels565_rev (GLcontext
* ctx
, GLint x
, GLint y
,
1335 GLsizei width
, GLsizei height
,
1336 GLenum format
, GLenum type
,
1337 const struct gl_pixelstore_attrib
*unpack
,
1338 const GLvoid
* pixels
)
1340 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1341 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1343 const struct gl_pixelstore_attrib
*finalUnpack
;
1344 struct gl_pixelstore_attrib scissoredUnpack
;
1346 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
1347 ctx
->Pixel
.ZoomY
!= 1.0F
||
1348 (ctx
->_ImageTransferState
& (IMAGE_SCALE_BIAS_BIT
|
1349 IMAGE_MAP_COLOR_BIT
)) ||
1350 (swrast
->_RasterMask
& (ALPHATEST_BIT
|
1351 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
1352 DEPTH_BIT
| /* could be done with RGB:DEPTH */
1353 FOG_BIT
| /* could be done with RGB:DEPTH */
1355 /*CLIP_BIT |*/ /* clipping ok, below */
1359 OCCLUSION_BIT
| /* nope! at least not yet */
1364 _swrast_DrawPixels( ctx
, x
, y
, width
, height
, format
, type
,
1369 /* make sure the pixelpipe is configured correctly */
1370 fxSetupFXUnits(ctx
);
1372 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
1373 if (ctx
->Scissor
.Enabled
) {
1374 /* This is a bit tricky, but by carefully adjusting the px, py,
1375 * width, height, skipPixels and skipRows values we can do
1376 * scissoring without special code in the rendering loop.
1379 /* we'll construct a new pixelstore struct */
1380 finalUnpack
= &scissoredUnpack
;
1381 scissoredUnpack
= *unpack
;
1382 if (scissoredUnpack
.RowLength
== 0)
1383 scissoredUnpack
.RowLength
= width
;
1386 if (x
< ctx
->Scissor
.X
) {
1387 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- x
);
1388 width
-= (ctx
->Scissor
.X
- x
);
1392 if (x
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
1393 width
-= (x
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
1396 if (y
< ctx
->Scissor
.Y
) {
1397 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- y
);
1398 height
-= (ctx
->Scissor
.Y
- y
);
1402 if (y
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
1403 height
-= (y
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
1406 if (width
<= 0 || height
<= 0)
1410 finalUnpack
= unpack
;
1413 info
.size
= sizeof(info
);
1414 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
1416 GR_LFBWRITEMODE_565
,
1417 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
1418 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1423 const GLint winX
= 0;
1424 const GLint winY
= 0;
1426 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
1427 GLushort
*dst
= (GLushort
*) info
.lfbPtr
+ (winY
+ y
) * dstStride
+ (winX
+ x
);
1429 if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1431 for (row
= 0; row
< height
; row
++) {
1432 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1433 pixels
, width
, height
, format
, type
, row
, 0);
1435 for (col
= 0; col
< width
; col
++) {
1436 dst
[col
] = TDFXPACKCOLOR565(src
[0], src
[1], src
[2]);
1442 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1444 for (row
= 0; row
< height
; row
++) {
1445 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1446 pixels
, width
, height
, format
, type
, row
, 0);
1448 for (col
= 0; col
< width
; col
++) {
1449 dst
[col
] = TDFXPACKCOLOR565(src
[0], src
[1], src
[2]);
1456 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1457 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1463 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1468 fxDDDrawPixels8888 (GLcontext
* ctx
, GLint x
, GLint y
,
1469 GLsizei width
, GLsizei height
,
1470 GLenum format
, GLenum type
,
1471 const struct gl_pixelstore_attrib
*unpack
,
1472 const GLvoid
* pixels
)
1474 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1475 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1477 const struct gl_pixelstore_attrib
*finalUnpack
;
1478 struct gl_pixelstore_attrib scissoredUnpack
;
1480 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
1481 ctx
->Pixel
.ZoomY
!= 1.0F
||
1482 (ctx
->_ImageTransferState
& (IMAGE_SCALE_BIAS_BIT
|
1483 IMAGE_MAP_COLOR_BIT
)) ||
1484 (swrast
->_RasterMask
& (/*ALPHATEST_BIT |*/
1485 /*BLEND_BIT |*/ /* blending ok, through pixpipe */
1486 DEPTH_BIT
| /* could be done with RGB:DEPTH */
1487 FOG_BIT
| /* could be done with RGB:DEPTH */
1489 /*CLIP_BIT |*/ /* clipping ok, below */
1491 /*MASKING_BIT |*/ /* masking ok, we're in 32bpp */
1493 OCCLUSION_BIT
| /* nope! at least not yet */
1498 _swrast_DrawPixels( ctx
, x
, y
, width
, height
, format
, type
,
1503 /* make sure the pixelpipe is configured correctly */
1504 fxSetupFXUnits(ctx
);
1506 /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
1507 if (ctx
->Scissor
.Enabled
) {
1508 /* This is a bit tricky, but by carefully adjusting the px, py,
1509 * width, height, skipPixels and skipRows values we can do
1510 * scissoring without special code in the rendering loop.
1513 /* we'll construct a new pixelstore struct */
1514 finalUnpack
= &scissoredUnpack
;
1515 scissoredUnpack
= *unpack
;
1516 if (scissoredUnpack
.RowLength
== 0)
1517 scissoredUnpack
.RowLength
= width
;
1520 if (x
< ctx
->Scissor
.X
) {
1521 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- x
);
1522 width
-= (ctx
->Scissor
.X
- x
);
1526 if (x
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
1527 width
-= (x
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
1530 if (y
< ctx
->Scissor
.Y
) {
1531 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- y
);
1532 height
-= (ctx
->Scissor
.Y
- y
);
1536 if (y
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
1537 height
-= (y
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
1540 if (width
<= 0 || height
<= 0)
1544 finalUnpack
= unpack
;
1547 info
.size
= sizeof(info
);
1548 if (!grLfbLock(GR_LFB_WRITE_ONLY
,
1550 GR_LFBWRITEMODE_8888
,
1551 GR_ORIGIN_LOWER_LEFT
, FXTRUE
, &info
)) {
1552 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1557 const GLint winX
= 0;
1558 const GLint winY
= 0;
1560 const GLint dstStride
= info
.strideInBytes
/ 4; /* stride in GLuints */
1561 GLuint
*dst
= (GLuint
*) info
.lfbPtr
+ (winY
+ y
) * dstStride
+ (winX
+ x
);
1563 if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
1564 /* directly memcpy 8A8R8G8B pixels to screen */
1565 const GLint widthInBytes
= width
* 4;
1567 for (row
= 0; row
< height
; row
++) {
1568 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1569 pixels
, width
, height
, format
, type
, row
, 0);
1570 MEMCPY(dst
, src
, widthInBytes
);
1574 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
1576 for (row
= 0; row
< height
; row
++) {
1577 GLubyte
*src
= (GLubyte
*) _mesa_image_address2d(finalUnpack
,
1578 pixels
, width
, height
, format
, type
, row
, 0);
1580 for (col
= 0; col
< width
; col
++) {
1581 dst
[col
] = TDFXPACKCOLOR8888(src
[2], src
[1], src
[0], 255);
1588 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1589 _swrast_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, finalUnpack
, pixels
);
1595 grLfbUnlock(GR_LFB_WRITE_ONLY
, fxMesa
->currentFB
);
1600 fxDDFinish(GLcontext
* ctx
)
1609 /* KW: Put the word Mesa in the render string because quakeworld
1610 * checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE).
1613 static const GLubyte
*
1614 fxDDGetString(GLcontext
* ctx
, GLenum name
)
1616 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1620 return (GLubyte
*)fxMesa
->rendererString
;
1621 #if __WIN32__ /* hack to advertise vanilla extension names */
1623 if (ctx
->Extensions
.String
== NULL
) {
1624 GLubyte
*ext
= _mesa_make_extension_string(ctx
);
1626 ctx
->Extensions
.String
= _mesa_malloc(strlen((char *)ext
) + 256);
1627 if (ctx
->Extensions
.String
!= NULL
) {
1628 strcpy((char *)ctx
->Extensions
.String
, (char *)ext
);
1629 /* put any additional extension names here */
1631 strcat((char *)ctx
->Extensions
.String
, " 3DFX_set_global_palette");
1634 strcat((char *)ctx
->Extensions
.String
, " WGL_3DFX_gamma_control");
1635 strcat((char *)ctx
->Extensions
.String
, " WGL_EXT_swap_control");
1636 strcat((char *)ctx
->Extensions
.String
, " WGL_EXT_extensions_string WGL_ARB_extensions_string");
1638 /* put any additional extension names here */
1641 ctx
->Extensions
.String
= ext
;
1645 return ctx
->Extensions
.String
;
1652 static const struct tnl_pipeline_stage
*fx_pipeline
[] = {
1653 &_tnl_vertex_transform_stage
, /* XXX todo - Add the fastpath here */
1654 &_tnl_normal_transform_stage
,
1655 &_tnl_lighting_stage
,
1656 &_tnl_fog_coordinate_stage
,
1658 &_tnl_texture_transform_stage
,
1659 &_tnl_point_attenuation_stage
,
1660 #if defined(FEATURE_NV_vertex_program) || defined(FEATURE_ARB_vertex_program)
1661 &_tnl_arb_vertex_program_stage
,
1662 &_tnl_vertex_program_stage
,
1672 fxDDInitFxMesaContext(fxMesaContext fxMesa
)
1674 GLcontext
*ctx
= fxMesa
->glCtx
;
1676 FX_setupGrVertexLayout();
1678 fxMesa
->color
= 0xffffffff;
1682 fxMesa
->stats
.swapBuffer
= 0;
1683 fxMesa
->stats
.reqTexUpload
= 0;
1684 fxMesa
->stats
.texUpload
= 0;
1685 fxMesa
->stats
.memTexUpload
= 0;
1687 fxMesa
->tmuSrc
= FX_TMU_NONE
;
1688 fxMesa
->lastUnitsMode
= FX_UM_NONE
;
1691 /* FX units setup */
1693 fxMesa
->unitsState
.alphaTestEnabled
= GL_FALSE
;
1694 fxMesa
->unitsState
.alphaTestFunc
= GL_ALWAYS
;
1695 fxMesa
->unitsState
.alphaTestRefValue
= 0.0;
1697 fxMesa
->unitsState
.blendEnabled
= GL_FALSE
;
1698 fxMesa
->unitsState
.blendSrcFuncRGB
= GR_BLEND_ONE
;
1699 fxMesa
->unitsState
.blendDstFuncRGB
= GR_BLEND_ZERO
;
1700 fxMesa
->unitsState
.blendSrcFuncAlpha
= GR_BLEND_ONE
;
1701 fxMesa
->unitsState
.blendDstFuncAlpha
= GR_BLEND_ZERO
;
1702 fxMesa
->unitsState
.blendEqRGB
= GR_BLEND_OP_ADD
;
1703 fxMesa
->unitsState
.blendEqAlpha
= GR_BLEND_OP_ADD
;
1705 fxMesa
->unitsState
.depthTestEnabled
= GL_FALSE
;
1706 fxMesa
->unitsState
.depthMask
= GL_TRUE
;
1707 fxMesa
->unitsState
.depthTestFunc
= GL_LESS
;
1708 fxMesa
->unitsState
.depthBias
= 0;
1710 fxMesa
->unitsState
.stencilWriteMask
= 0xff;
1712 if (fxMesa
->colDepth
== 32) {
1714 fxMesa
->Glide
.grColorMaskExt(FXTRUE
, FXTRUE
, FXTRUE
, fxMesa
->haveHwAlpha
);
1716 /* 15/16 bpp mode */
1717 grColorMask(FXTRUE
, fxMesa
->haveHwAlpha
);
1720 fxMesa
->currentFB
= fxMesa
->haveDoubleBuffer
? GR_BUFFER_BACKBUFFER
: GR_BUFFER_FRONTBUFFER
;
1721 grRenderBuffer(fxMesa
->currentFB
);
1723 fxMesa
->state
= MALLOC(FX_grGetInteger(GR_GLIDE_STATE_SIZE
));
1724 fxMesa
->fogTable
= (GrFog_t
*) MALLOC(FX_grGetInteger(GR_FOG_TABLE_ENTRIES
) *
1727 if (!fxMesa
->state
|| !fxMesa
->fogTable
) {
1729 FREE(fxMesa
->state
);
1730 if (fxMesa
->fogTable
)
1731 FREE(fxMesa
->fogTable
);
1735 if (fxMesa
->haveZBuffer
) {
1736 grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER
);
1739 if (!fxMesa
->bgrOrder
) {
1740 grLfbWriteColorFormat(GR_COLORFORMAT_ABGR
);
1743 if (fxMesa
->Glide
.grSetNumPendingBuffers
!= NULL
) {
1744 fxMesa
->Glide
.grSetNumPendingBuffers(fxMesa
->maxPendingSwapBuffers
);
1747 fxMesa
->textureAlign
= FX_grGetInteger(GR_TEXTURE_ALIGN
);
1751 int textureLevels
= 0;
1752 int textureSize
= FX_grGetInteger(GR_MAX_TEXTURE_SIZE
);
1755 } while ((textureSize
>>= 0x1) & 0x7ff);
1756 ctx
->Const
.MaxTextureLevels
= textureLevels
;
1757 ctx
->Const
.MaxTextureLodBias
= /*textureLevels - 1*/8; /* Glide bug */
1758 #if FX_RESCALE_BIG_TEXURES_HACK
1759 fxMesa
->textureMaxLod
= textureLevels
- 1;
1760 if ((env
= getenv("MESA_FX_MAXLOD")) != NULL
) {
1761 int maxLevels
= atoi(env
) + 1;
1762 if ((maxLevels
<= MAX_TEXTURE_LEVELS
) && (maxLevels
> textureLevels
)) {
1763 ctx
->Const
.MaxTextureLevels
= maxLevels
;
1768 ctx
->Const
.MaxTextureCoordUnits
=
1769 ctx
->Const
.MaxTextureImageUnits
= fxMesa
->haveTwoTMUs
? 2 : 1;
1770 ctx
->Const
.MaxTextureUnits
= MAX2(ctx
->Const
.MaxTextureImageUnits
, ctx
->Const
.MaxTextureCoordUnits
);
1772 fxMesa
->new_state
= _NEW_ALL
;
1773 if (!fxMesa
->haveHwStencil
) {
1774 /* don't touch stencil if there is none */
1775 fxMesa
->new_state
&= ~FX_NEW_STENCIL
;
1778 /* Initialize the software rasterizer and helper modules.
1780 _swrast_CreateContext(ctx
);
1781 _ac_CreateContext(ctx
);
1782 _tnl_CreateContext(ctx
);
1783 _swsetup_CreateContext(ctx
);
1785 /* Install customized pipeline */
1786 _tnl_destroy_pipeline(ctx
);
1787 _tnl_install_pipeline(ctx
, fx_pipeline
);
1791 fxSetupDDPointers(ctx
);
1792 fxDDInitTriFuncs(ctx
);
1794 /* Tell the software rasterizer to use pixel fog always.
1796 _swrast_allow_vertex_fog(ctx
, GL_FALSE
);
1797 _swrast_allow_pixel_fog(ctx
, GL_TRUE
);
1798 _tnl_allow_vertex_fog( ctx
, GL_FALSE
);
1799 _tnl_allow_pixel_fog( ctx
, GL_TRUE
);
1801 /* Tell tnl not to calculate or use vertex fog factors. (Needed to
1802 * tell render stage not to clip fog coords).
1804 /* _tnl_calculate_vertex_fog( ctx, GL_FALSE ); */
1806 fxDDInitExtensions(ctx
);
1809 /* do we want dither? It just looks bad... */
1810 grEnable(GR_ALLOW_MIPMAP_DITHER
);
1812 grGlideGetState((GrState
*) fxMesa
->state
);
1820 fxDDDestroyFxMesaContext(fxMesaContext fxMesa
)
1822 _swsetup_DestroyContext(fxMesa
->glCtx
);
1823 _tnl_DestroyContext(fxMesa
->glCtx
);
1824 _ac_DestroyContext(fxMesa
->glCtx
);
1825 _swrast_DestroyContext(fxMesa
->glCtx
);
1828 FREE(fxMesa
->state
);
1829 if (fxMesa
->fogTable
)
1830 FREE(fxMesa
->fogTable
);
1831 fxFreeVB(fxMesa
->glCtx
);
1838 fxDDInitExtensions(GLcontext
* ctx
)
1840 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1842 #if 1 /* multipass ColorSum stage */
1843 _mesa_enable_extension(ctx
, "GL_EXT_secondary_color");
1846 _mesa_enable_extension(ctx
, "GL_ARB_point_sprite");
1847 _mesa_enable_extension(ctx
, "GL_EXT_point_parameters");
1848 _mesa_enable_extension(ctx
, "GL_EXT_paletted_texture");
1849 _mesa_enable_extension(ctx
, "GL_EXT_texture_lod_bias");
1850 _mesa_enable_extension(ctx
, "GL_EXT_shared_texture_palette");
1851 _mesa_enable_extension(ctx
, "GL_EXT_blend_func_separate");
1852 _mesa_enable_extension(ctx
, "GL_EXT_texture_env_add");
1853 _mesa_enable_extension(ctx
, "GL_EXT_stencil_wrap");
1854 _mesa_enable_extension(ctx
, "GL_EXT_stencil_two_side");
1856 if (fxMesa
->haveTwoTMUs
) {
1857 _mesa_enable_extension(ctx
, "GL_ARB_multitexture");
1860 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1861 _mesa_enable_extension(ctx
, "GL_ARB_texture_compression");
1862 _mesa_enable_extension(ctx
, "GL_3DFX_texture_compression_FXT1");
1863 _mesa_enable_extension(ctx
, "GL_EXT_texture_compression_s3tc");
1864 _mesa_enable_extension(ctx
, "GL_S3_s3tc");
1865 _mesa_enable_extension(ctx
, "GL_NV_blend_square");
1868 * We should enable generic texture compression functions,
1869 * but some poorly written apps automatically assume S3TC.
1870 * Binding NCC to GL_COMPRESSED_RGB[A] is an unnecessary hassle,
1871 * since it's slow and ugly (better with palette textures, then).
1872 * Moreover, NCC is not an OpenGL standard, so we can't use
1873 * precompressed textures. Last, but not least, NCC runs amok
1874 * when multitexturing on a Voodoo3 and up (see POINTCAST vs UMA).
1875 * Note: this is also a problem with palette textures, but
1876 * faking multitex by multipass is evil...
1877 * Implementing NCC requires three stages:
1878 * fxDDChooseTextureFormat:
1879 * bind GL_COMPRESSED_RGB[A] to _mesa_texformat_argb8888,
1880 * so we can quantize properly, at a later time
1882 * if GL_COMPRESSED_RGB
1883 * use _mesa_texformat_l8 to get 1bpt and set GR_TEXFMT_YIQ_422
1884 * if GL_COMPRESSED_RGBA
1885 * use _mesa_texformat_al88 to get 2bpt and set GR_TEXFMT_AYIQ_8422
1886 * txMipQuantize(...);
1888 * txPalToNcc((GuNccTable *)(&(ti->palette)), pxMip.pal);
1890 * fxSetupSingleTMU_NoLock/fxSetupDoubleTMU_NoLock:
1891 * grTexDownloadTable(GR_TEXTABLE_NCC0, &(ti->palette));
1893 /*_mesa_enable_extension(ctx, "GL_ARB_texture_compression");*/
1894 _mesa_enable_extension(ctx
, "GL_SGIS_generate_mipmap");
1897 if (fxMesa
->HaveCmbExt
) {
1898 _mesa_enable_extension(ctx
, "GL_ARB_texture_env_combine");
1899 _mesa_enable_extension(ctx
, "GL_EXT_texture_env_combine");
1902 if (fxMesa
->HavePixExt
) {
1903 _mesa_enable_extension(ctx
, "GL_EXT_blend_subtract");
1904 _mesa_enable_extension(ctx
, "GL_EXT_blend_equation_separate");
1907 if (fxMesa
->HaveMirExt
) {
1908 _mesa_enable_extension(ctx
, "GL_ARB_texture_mirrored_repeat");
1911 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo2
) {
1912 _mesa_enable_extension(ctx
, "GL_EXT_fog_coord");
1915 /* core-level extensions */
1916 _mesa_enable_extension(ctx
, "GL_EXT_multi_draw_arrays");
1917 _mesa_enable_extension(ctx
, "GL_IBM_multimode_draw_arrays");
1918 _mesa_enable_extension(ctx
, "GL_ARB_vertex_buffer_object");
1920 if (getenv("MESA_FX_ALLOW_VP")) {
1921 _mesa_enable_extension(ctx
, "GL_ARB_vertex_program");
1922 _mesa_enable_extension(ctx
, "GL_NV_vertex_program");
1923 _mesa_enable_extension(ctx
, "GL_NV_vertex_program1_1");
1924 _mesa_enable_extension(ctx
, "GL_MESA_program_debug");
1927 /* this requires _tnl_vertex_cull_stage in the pipeline */
1928 _mesa_enable_extension(ctx
, "EXT_cull_vertex");
1933 /************************************************************************/
1934 /************************************************************************/
1935 /************************************************************************/
1937 /* Check if the hardware supports the current context
1939 * Performs similar work to fxDDChooseRenderState() - should be merged.
1942 fx_check_IsInHardware(GLcontext
* ctx
)
1944 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1946 if (ctx
->RenderMode
!= GL_RENDER
) {
1947 return FX_FALLBACK_RENDER_MODE
;
1950 if (ctx
->Stencil
.Enabled
&& !fxMesa
->haveHwStencil
) {
1951 return FX_FALLBACK_STENCIL
;
1954 if (ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] != BUFFER_BIT_FRONT_LEFT
&&
1955 ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] != BUFFER_BIT_BACK_LEFT
) {
1956 return FX_FALLBACK_DRAW_BUFFER
;
1959 if (ctx
->Color
.BlendEnabled
) {
1960 if (ctx
->Color
.BlendEquationRGB
!= GL_FUNC_ADD
) {
1961 if (!fxMesa
->HavePixExt
||
1962 ((ctx
->Color
.BlendEquationRGB
!= GL_FUNC_SUBTRACT
) &&
1963 (ctx
->Color
.BlendEquationRGB
!= GL_FUNC_REVERSE_SUBTRACT
))) {
1964 return FX_FALLBACK_BLEND
;
1968 if (ctx
->Color
.BlendEquationA
!= GL_FUNC_ADD
) {
1969 if (!fxMesa
->HavePixExt
||
1970 ((ctx
->Color
.BlendEquationA
!= GL_FUNC_SUBTRACT
) &&
1971 (ctx
->Color
.BlendEquationA
!= GL_FUNC_REVERSE_SUBTRACT
))) {
1972 return FX_FALLBACK_BLEND
;
1978 * We fail the spec here, unless certain blending modes:
1979 * RGB: (GL_ONE + GL_*) or (GL_ZERO + GL_*) or ...
1981 if (NEED_SECONDARY_COLOR(ctx
)) {
1982 if ((ctx
->Color
.BlendEquationRGB
!= GL_FUNC_ADD
) &&
1983 (ctx
->Color
.BlendSrcRGB
!= GL_ONE
)) {
1984 /* Can't use multipass to blend ColorSum stage */
1985 return FX_FALLBACK_SPECULAR
;
1992 * We could avoid this for certain `sfactor/dfactor'
1993 * I do not think that is even worthwhile to check
1994 * because if someone is using blending they use more
1995 * interesting settings and also it would add more
1996 * state tracking to a lot of the code.
1998 if (ctx
->Color
.ColorLogicOpEnabled
&& (ctx
->Color
.LogicOp
!= GL_COPY
)) {
1999 return FX_FALLBACK_LOGICOP
;
2002 if ((fxMesa
->colDepth
!= 32) &&
2003 ((ctx
->Color
.ColorMask
[RCOMP
] != ctx
->Color
.ColorMask
[GCOMP
]) ||
2004 (ctx
->Color
.ColorMask
[GCOMP
] != ctx
->Color
.ColorMask
[BCOMP
]))) {
2005 return FX_FALLBACK_COLORMASK
;
2008 /* Unsupported texture/multitexture cases */
2010 /* we can only do 1D/2D textures */
2011 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& ~(TEXTURE_1D_BIT
|TEXTURE_2D_BIT
))
2012 return FX_FALLBACK_TEXTURE_MAP
;
2014 if (fxMesa
->haveTwoTMUs
) {
2015 if (ctx
->Texture
.Unit
[1]._ReallyEnabled
& ~(TEXTURE_1D_BIT
|TEXTURE_2D_BIT
))
2016 return FX_FALLBACK_TEXTURE_MAP
;
2018 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
) {
2019 if (fxMesa
->type
< GR_SSTTYPE_Voodoo2
)
2020 if (ctx
->Texture
.Unit
[0].EnvMode
== GL_BLEND
&&
2021 (ctx
->Texture
.Unit
[1]._ReallyEnabled
||
2022 ctx
->Texture
.Unit
[0].EnvColor
[0] != 0 ||
2023 ctx
->Texture
.Unit
[0].EnvColor
[1] != 0 ||
2024 ctx
->Texture
.Unit
[0].EnvColor
[2] != 0 ||
2025 ctx
->Texture
.Unit
[0].EnvColor
[3] != 1)) {
2026 return FX_FALLBACK_TEXTURE_ENV
;
2028 if (ctx
->Texture
.Unit
[0]._Current
->Image
[0][0]->Border
> 0)
2029 return FX_FALLBACK_TEXTURE_BORDER
;
2032 if (ctx
->Texture
.Unit
[1]._ReallyEnabled
) {
2033 if (fxMesa
->type
< GR_SSTTYPE_Voodoo2
)
2034 if (ctx
->Texture
.Unit
[1].EnvMode
== GL_BLEND
)
2035 return FX_FALLBACK_TEXTURE_ENV
;
2036 if (ctx
->Texture
.Unit
[1]._Current
->Image
[0][0]->Border
> 0)
2037 return FX_FALLBACK_TEXTURE_BORDER
;
2040 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
2041 fprintf(stderr
, "fx_check_IsInHardware: envmode is %s/%s\n",
2042 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[0].EnvMode
),
2043 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[1].EnvMode
));
2045 /* KW: This was wrong (I think) and I changed it... which doesn't mean
2046 * it is now correct...
2047 * BP: The old condition just seemed to test if both texture units
2048 * were enabled. That's easy!
2050 if (ctx
->Texture
._EnabledUnits
== 0x3) {
2052 /* Can't use multipass to blend a multitextured triangle - fall
2055 if (!fxMesa
->haveTwoTMUs
&& ctx
->Color
.BlendEnabled
) {
2056 return FX_FALLBACK_TEXTURE_MULTI
;
2060 if (!fxMesa
->HaveCmbExt
&&
2061 (ctx
->Texture
.Unit
[0].EnvMode
!= ctx
->Texture
.Unit
[1].EnvMode
) &&
2062 (ctx
->Texture
.Unit
[0].EnvMode
!= GL_MODULATE
) &&
2063 (ctx
->Texture
.Unit
[0].EnvMode
!= GL_REPLACE
)) { /* q2, seems ok... */
2064 if (TDFX_DEBUG
& VERBOSE_DRIVER
)
2065 fprintf(stderr
, "fx_check_IsInHardware: unsupported multitex env mode\n");
2066 return FX_FALLBACK_TEXTURE_MULTI
;
2071 /* we have just one texture unit */
2072 if (ctx
->Texture
._EnabledUnits
> 0x1) {
2073 return FX_FALLBACK_TEXTURE_MULTI
;
2076 if (fxMesa
->type
< GR_SSTTYPE_Voodoo2
)
2077 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
&&
2078 (ctx
->Texture
.Unit
[0].EnvMode
== GL_BLEND
)) {
2079 return FX_FALLBACK_TEXTURE_ENV
;
2089 fxDDUpdateDDPointers(GLcontext
* ctx
, GLuint new_state
)
2091 /* TNLcontext *tnl = TNL_CONTEXT(ctx); */
2092 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2094 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
2095 fprintf(stderr
, "fxDDUpdateDDPointers(%08x)\n", new_state
);
2098 _swrast_InvalidateState(ctx
, new_state
);
2099 _ac_InvalidateState(ctx
, new_state
);
2100 _tnl_InvalidateState(ctx
, new_state
);
2101 _swsetup_InvalidateState(ctx
, new_state
);
2103 fxMesa
->new_gl_state
|= new_state
;
2110 fxSetupDDPointers(GLcontext
* ctx
)
2112 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2113 /* TNLcontext *tnl = TNL_CONTEXT(ctx); */
2115 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
2116 fprintf(stderr
, "fxSetupDDPointers()\n");
2119 ctx
->Driver
.UpdateState
= fxDDUpdateDDPointers
;
2120 ctx
->Driver
.GetString
= fxDDGetString
;
2121 ctx
->Driver
.ClearIndex
= NULL
;
2122 ctx
->Driver
.ClearColor
= fxDDClearColor
;
2123 ctx
->Driver
.Clear
= fxDDClear
;
2124 ctx
->Driver
.DrawBuffer
= fxDDSetDrawBuffer
;
2125 ctx
->Driver
.GetBufferSize
= fxDDGetBufferSize
;
2126 ctx
->Driver
.Viewport
= fxDDViewport
;
2127 switch (fxMesa
->colDepth
) {
2129 ctx
->Driver
.DrawPixels
= fxDDDrawPixels555
;
2130 ctx
->Driver
.ReadPixels
= fxDDReadPixels555
;
2131 ctx
->Driver
.Bitmap
= fxDDDrawBitmap2
;
2134 ctx
->Driver
.DrawPixels
= !fxMesa
->bgrOrder
? fxDDDrawPixels565
: fxDDDrawPixels565_rev
;
2135 ctx
->Driver
.ReadPixels
= fxDDReadPixels565
;
2136 ctx
->Driver
.Bitmap
= fxDDDrawBitmap2
;
2139 ctx
->Driver
.DrawPixels
= fxDDDrawPixels8888
;
2140 ctx
->Driver
.ReadPixels
= fxDDReadPixels8888
;
2141 ctx
->Driver
.Bitmap
= fxDDDrawBitmap4
;
2144 ctx
->Driver
.Finish
= fxDDFinish
;
2145 ctx
->Driver
.Flush
= NULL
;
2146 ctx
->Driver
.ChooseTextureFormat
= fxDDChooseTextureFormat
;
2147 ctx
->Driver
.TexImage1D
= fxDDTexImage1D
;
2148 ctx
->Driver
.TexImage2D
= fxDDTexImage2D
;
2149 ctx
->Driver
.TexSubImage1D
= fxDDTexSubImage1D
;
2150 ctx
->Driver
.TexSubImage2D
= fxDDTexSubImage2D
;
2151 ctx
->Driver
.CompressedTexImage2D
= fxDDCompressedTexImage2D
;
2152 ctx
->Driver
.CompressedTexSubImage2D
= fxDDCompressedTexSubImage2D
;
2153 ctx
->Driver
.TestProxyTexImage
= fxDDTestProxyTexImage
;
2154 ctx
->Driver
.TexEnv
= fxDDTexEnv
;
2155 ctx
->Driver
.TexParameter
= fxDDTexParam
;
2156 ctx
->Driver
.BindTexture
= fxDDTexBind
;
2157 ctx
->Driver
.DeleteTexture
= fxDDTexDel
;
2158 ctx
->Driver
.IsTextureResident
= fxDDIsTextureResident
;
2159 ctx
->Driver
.UpdateTexturePalette
= fxDDTexPalette
;
2160 ctx
->Driver
.AlphaFunc
= fxDDAlphaFunc
;
2161 ctx
->Driver
.BlendFuncSeparate
= fxDDBlendFuncSeparate
;
2162 ctx
->Driver
.BlendEquationSeparate
= fxDDBlendEquationSeparate
;
2163 ctx
->Driver
.DepthFunc
= fxDDDepthFunc
;
2164 ctx
->Driver
.DepthMask
= fxDDDepthMask
;
2165 ctx
->Driver
.ColorMask
= fxDDColorMask
;
2166 ctx
->Driver
.Fogfv
= fxDDFogfv
;
2167 ctx
->Driver
.Scissor
= fxDDScissor
;
2168 ctx
->Driver
.FrontFace
= fxDDFrontFace
;
2169 ctx
->Driver
.CullFace
= fxDDCullFace
;
2170 ctx
->Driver
.ShadeModel
= fxDDShadeModel
;
2171 ctx
->Driver
.Enable
= fxDDEnable
;
2172 if (fxMesa
->haveHwStencil
) {
2173 ctx
->Driver
.StencilFuncSeparate
= fxDDStencilFuncSeparate
;
2174 ctx
->Driver
.StencilMaskSeparate
= fxDDStencilMaskSeparate
;
2175 ctx
->Driver
.StencilOpSeparate
= fxDDStencilOpSeparate
;
2178 fxSetupDDSpanPointers(ctx
);
2179 fxDDUpdateDDPointers(ctx
, ~0);
2187 * Need this to provide at least one external definition.
2190 extern int gl_fx_dummy_function_dd(void);
2192 gl_fx_dummy_function_dd(void)