1 /* $Id: s_span.c,v 1.21 2002/01/10 16:54:29 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 * pixel span rasterization:
30 * These functions implement the rasterization pipeline.
41 #include "s_alphabuf.h"
43 #include "s_context.h"
47 #include "s_masking.h"
48 #include "s_scissor.h"
50 #include "s_stencil.h"
51 #include "s_texture.h"
54 static void SET_MASK_TO_ONE(struct sw_span
*span
) {
55 SW_SPAN_SET_FLAG(span
->filledMask
);
56 /* init mask to 1's (all pixels are to be written) */
57 MEMSET(span
->mask
, 1, span
->end
);
62 * Apply the current polygon stipple pattern to a span of pixels.
65 old_stipple_polygon_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
68 const GLuint highbit
= 0x80000000;
71 stipple
= ctx
->PolygonStipple
[y
% 32];
72 m
= highbit
>> (GLuint
) (x
% 32);
74 for (i
= 0; i
< n
; i
++) {
75 if ((m
& stipple
) == 0) {
86 * Apply the current polygon stipple pattern to a span of pixels.
89 stipple_polygon_span( GLcontext
*ctx
, struct sw_span
*span
)
91 const GLuint highbit
= 0x80000000;
94 ASSERT (span
->filledMask
== GL_TRUE
);
96 stipple
= ctx
->PolygonStipple
[span
->y
% 32];
97 m
= highbit
>> (GLuint
) (span
->x
% 32);
99 for (i
= 0; i
< span
->end
; i
++) {
100 if ((m
& stipple
) == 0) {
108 span
->write_all
= GL_FALSE
;
114 * Clip a pixel span to the current buffer/window boundaries.
115 * Return: 'n' such that pixel 'n', 'n+1' etc. are clipped,
117 * 0 = all pixels clipped
120 old_clip_span( GLcontext
*ctx
, GLint n
, GLint x
, GLint y
, GLubyte mask
[] )
122 /* Clip to top and bottom */
123 if (y
< 0 || y
>= ctx
->DrawBuffer
->Height
) {
127 /* Clip to the left */
130 /* completely off left side */
134 /* partially off left side */
135 BZERO(mask
, -x
* sizeof(GLubyte
));
140 if (x
+ n
> ctx
->DrawBuffer
->Width
) {
141 if (x
>= ctx
->DrawBuffer
->Width
) {
142 /* completely off right side */
146 /* partially off right side */
147 return ctx
->DrawBuffer
->Width
- x
;
156 * Clip a pixel span to the current buffer/window boundaries.
157 * Return: GL_TRUE some pixel still visible
158 * GL_FALSE nothing visible
161 clip_span( GLcontext
*ctx
, struct sw_span
*span
)
163 GLint x
= span
->x
, y
= span
->y
, n
= span
->end
;
165 ASSERT (span
->filledMask
== GL_TRUE
);
167 /* Clip to top and bottom */
168 if (y
< 0 || y
>= ctx
->DrawBuffer
->Height
) {
173 /* Clip to the left */
176 /* completely off left side */
181 /* partially off left side */
182 span
->write_all
= GL_FALSE
;
183 BZERO(span
->mask
, -x
* sizeof(GLubyte
));
189 if (x
+ n
> ctx
->DrawBuffer
->Width
) {
190 if (x
>= ctx
->DrawBuffer
->Width
) {
191 /* completely off right side */
196 /* partially off right side */
197 span
->end
= ctx
->DrawBuffer
->Width
- x
;
208 * Draw to more than one color buffer (or none).
211 multi_write_index_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
212 const GLuint indexes
[], const GLubyte mask
[] )
214 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
217 if (ctx
->Color
.DrawBuffer
== GL_NONE
)
220 /* loop over four possible dest color buffers */
221 for (bufferBit
= 1; bufferBit
<= 8; bufferBit
= bufferBit
<< 1) {
222 if (bufferBit
& ctx
->Color
.DrawDestMask
) {
223 GLuint indexTmp
[MAX_WIDTH
];
224 ASSERT(n
< MAX_WIDTH
);
226 if (bufferBit
== FRONT_LEFT_BIT
)
227 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, GL_FRONT_LEFT
);
228 else if (bufferBit
== FRONT_RIGHT_BIT
)
229 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, GL_FRONT_RIGHT
);
230 else if (bufferBit
== BACK_LEFT_BIT
)
231 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, GL_BACK_LEFT
);
233 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, GL_BACK_RIGHT
);
235 /* make copy of incoming indexes */
236 MEMCPY( indexTmp
, indexes
, n
* sizeof(GLuint
) );
237 if (ctx
->Color
.IndexLogicOpEnabled
) {
238 _mesa_logicop_ci_span( ctx
, n
, x
, y
, indexTmp
, mask
);
240 if (ctx
->Color
.IndexMask
== 0) {
243 else if (ctx
->Color
.IndexMask
!= 0xffffffff) {
244 _mesa_mask_index_span( ctx
, n
, x
, y
, indexTmp
);
246 (*swrast
->Driver
.WriteCI32Span
)( ctx
, n
, x
, y
, indexTmp
, mask
);
250 /* restore default dest buffer */
251 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, ctx
->Color
.DriverDrawBuffer
);
256 * Draw to more than one RGBA color buffer (or none).
259 multi_write_rgba_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
260 CONST GLchan rgba
[][4], const GLubyte mask
[] )
262 const GLuint colorMask
= *((GLuint
*) ctx
->Color
.ColorMask
);
264 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
266 if (ctx
->Color
.DrawBuffer
== GL_NONE
)
269 /* loop over four possible dest color buffers */
270 for (bufferBit
= 1; bufferBit
<= 8; bufferBit
= bufferBit
<< 1) {
271 if (bufferBit
& ctx
->Color
.DrawDestMask
) {
272 GLchan rgbaTmp
[MAX_WIDTH
][4];
273 ASSERT(n
< MAX_WIDTH
);
275 if (bufferBit
== FRONT_LEFT_BIT
) {
276 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, GL_FRONT_LEFT
);
277 ctx
->DrawBuffer
->Alpha
= ctx
->DrawBuffer
->FrontLeftAlpha
;
279 else if (bufferBit
== FRONT_RIGHT_BIT
) {
280 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, GL_FRONT_RIGHT
);
281 ctx
->DrawBuffer
->Alpha
= ctx
->DrawBuffer
->FrontRightAlpha
;
283 else if (bufferBit
== BACK_LEFT_BIT
) {
284 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, GL_BACK_LEFT
);
285 ctx
->DrawBuffer
->Alpha
= ctx
->DrawBuffer
->BackLeftAlpha
;
288 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, GL_BACK_RIGHT
);
289 ctx
->DrawBuffer
->Alpha
= ctx
->DrawBuffer
->BackRightAlpha
;
292 /* make copy of incoming colors */
293 MEMCPY( rgbaTmp
, rgba
, 4 * n
* sizeof(GLchan
) );
295 if (ctx
->Color
.ColorLogicOpEnabled
) {
296 _mesa_logicop_rgba_span( ctx
, n
, x
, y
, rgbaTmp
, mask
);
298 else if (ctx
->Color
.BlendEnabled
) {
299 _mesa_blend_span( ctx
, n
, x
, y
, rgbaTmp
, mask
);
301 if (colorMask
== 0x0) {
304 else if (colorMask
!= 0xffffffff) {
305 _mesa_mask_rgba_span( ctx
, n
, x
, y
, rgbaTmp
);
308 (*swrast
->Driver
.WriteRGBASpan
)( ctx
, n
, x
, y
,
309 (const GLchan (*)[4]) rgbaTmp
, mask
);
310 if (swrast
->_RasterMask
& ALPHABUF_BIT
) {
311 _mesa_write_alpha_span( ctx
, n
, x
, y
,
312 (const GLchan (*)[4])rgbaTmp
, mask
);
317 /* restore default dest buffer */
318 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, ctx
->Color
.DriverDrawBuffer
);
324 * Write a horizontal span of color index pixels to the frame buffer.
325 * Stenciling, Depth-testing, etc. are done as needed.
326 * Input: n - number of pixels in the span
327 * x, y - location of leftmost pixel in the span
328 * z - array of [n] z-values
329 * fog - array of fog factor values in [0,1]
330 * index - array of [n] color indexes
331 * primitive - either GL_POINT, GL_LINE, GL_POLYGON, or GL_BITMAP
334 _old_write_index_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
335 const GLdepth z
[], const GLfloat fog
[],
336 GLuint indexIn
[], const GLint coverage
[],
339 const GLuint modBits
= FOG_BIT
| BLEND_BIT
| MASKING_BIT
| LOGIC_OP_BIT
;
340 GLubyte mask
[MAX_WIDTH
];
341 GLuint indexBackup
[MAX_WIDTH
];
342 GLuint
*index
; /* points to indexIn or indexBackup */
343 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
345 /* init mask to 1's (all pixels are to be written) */
348 if ((swrast
->_RasterMask
& WINCLIP_BIT
) || primitive
==GL_BITMAP
) {
349 if ((n
= old_clip_span(ctx
,n
,x
,y
,mask
)) == 0) {
354 if ((primitive
==GL_BITMAP
&& (swrast
->_RasterMask
& modBits
))
355 || (swrast
->_RasterMask
& MULTI_DRAW_BIT
)) {
356 /* Make copy of color indexes */
357 MEMCPY( indexBackup
, indexIn
, n
* sizeof(GLuint
) );
365 /* Do the scissor test */
366 if (ctx
->Scissor
.Enabled
) {
367 if ((n
= _old_scissor_span( ctx
, n
, x
, y
, mask
)) == 0) {
372 /* Polygon Stippling */
373 if (ctx
->Polygon
.StippleFlag
&& primitive
==GL_POLYGON
) {
374 old_stipple_polygon_span( ctx
, n
, x
, y
, mask
);
377 if (ctx
->Stencil
.Enabled
) {
378 /* first stencil test */
379 if (_old_stencil_and_ztest_span(ctx
, n
, x
, y
, z
, mask
) == GL_FALSE
) {
383 else if (ctx
->Depth
.Test
) {
384 /* regular depth testing */
385 if (_old_depth_test_span( ctx
, n
, x
, y
, z
, mask
) == 0)
389 /* if we get here, something passed the depth test */
390 ctx
->OcclusionResult
= GL_TRUE
;
393 if (ctx
->Fog
.Enabled
) {
394 if (fog
&& !swrast
->_PreferPixelFog
)
395 _old_fog_ci_pixels( ctx
, n
, fog
, index
);
397 _old_depth_fog_ci_pixels( ctx
, n
, z
, index
);
400 /* Antialias coverage application */
403 for (i
= 0; i
< n
; i
++) {
404 ASSERT(coverage
[i
] < 16);
405 index
[i
] = (index
[i
] & ~0xf) | coverage
[i
];
409 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
410 /* draw to zero or two or more buffers */
411 multi_write_index_span( ctx
, n
, x
, y
, index
, mask
);
414 /* normal situation: draw to exactly one buffer */
415 if (ctx
->Color
.IndexLogicOpEnabled
) {
416 _mesa_logicop_ci_span( ctx
, n
, x
, y
, index
, mask
);
419 if (ctx
->Color
.IndexMask
== 0) {
422 else if (ctx
->Color
.IndexMask
!= 0xffffffff) {
423 _mesa_mask_index_span( ctx
, n
, x
, y
, index
);
427 (*swrast
->Driver
.WriteCI32Span
)( ctx
, n
, x
, y
, index
, mask
);
433 * Apply fragment processing to a span of RGBA fragments.
435 * n - number of fragments in the span
436 * x,y - location of first (left) fragment
437 * fog - array of fog factor values in [0,1]
440 _old_write_rgba_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
441 const GLdepth z
[], const GLfloat fog
[],
442 GLchan rgbaIn
[][4], const GLfloat coverage
[],
445 const GLuint modBits
= FOG_BIT
| BLEND_BIT
| MASKING_BIT
|
446 LOGIC_OP_BIT
| TEXTURE_BIT
;
447 GLubyte mask
[MAX_WIDTH
];
448 GLboolean write_all
= GL_TRUE
;
449 GLchan rgbaBackup
[MAX_WIDTH
][4];
451 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
453 /* init mask to 1's (all pixels are to be written) */
456 if ((swrast
->_RasterMask
& WINCLIP_BIT
) || primitive
==GL_BITMAP
) {
457 if ((n
= old_clip_span( ctx
,n
,x
,y
,mask
)) == 0) {
461 write_all
= GL_FALSE
;
464 if ((primitive
==GL_BITMAP
&& (swrast
->_RasterMask
& modBits
))
465 || (swrast
->_RasterMask
& MULTI_DRAW_BIT
)) {
466 /* must make a copy of the colors since they may be modified */
467 MEMCPY( rgbaBackup
, rgbaIn
, 4 * n
* sizeof(GLchan
) );
474 /* Do the scissor test */
475 if (ctx
->Scissor
.Enabled
) {
476 if ((n
= _old_scissor_span( ctx
, n
, x
, y
, mask
)) == 0) {
480 write_all
= GL_FALSE
;
483 /* Polygon Stippling */
484 if (ctx
->Polygon
.StippleFlag
&& primitive
==GL_POLYGON
) {
485 old_stipple_polygon_span( ctx
, n
, x
, y
, mask
);
486 write_all
= GL_FALSE
;
489 /* Do the alpha test */
490 if (ctx
->Color
.AlphaEnabled
) {
491 if (_mesa_alpha_test( ctx
, n
, (const GLchan (*)[4]) rgba
, mask
) == 0) {
494 write_all
= GL_FALSE
;
497 if (ctx
->Stencil
.Enabled
) {
498 /* first stencil test */
499 if (_old_stencil_and_ztest_span(ctx
, n
, x
, y
, z
, mask
) == GL_FALSE
) {
502 write_all
= GL_FALSE
;
504 else if (ctx
->Depth
.Test
) {
505 /* regular depth testing */
506 GLuint m
= _old_depth_test_span( ctx
, n
, x
, y
, z
, mask
);
511 write_all
= GL_FALSE
;
515 /* if we get here, something passed the depth test */
516 ctx
->OcclusionResult
= GL_TRUE
;
519 if (ctx
->Fog
.Enabled
) {
520 if (fog
&& !swrast
->_PreferPixelFog
)
521 _old_fog_rgba_pixels( ctx
, n
, fog
, rgba
);
523 _old_depth_fog_rgba_pixels( ctx
, n
, z
, rgba
);
526 /* Antialias coverage application */
529 for (i
= 0; i
< n
; i
++) {
530 rgba
[i
][ACOMP
] = (GLchan
) (rgba
[i
][ACOMP
] * coverage
[i
]);
534 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
535 multi_write_rgba_span( ctx
, n
, x
, y
, (const GLchan (*)[4]) rgba
, mask
);
538 /* normal: write to exactly one buffer */
539 /* logic op or blending */
540 const GLuint colorMask
= *((GLuint
*) ctx
->Color
.ColorMask
);
542 if (ctx
->Color
.ColorLogicOpEnabled
) {
543 _mesa_logicop_rgba_span( ctx
, n
, x
, y
, rgba
, mask
);
545 else if (ctx
->Color
.BlendEnabled
) {
546 _mesa_blend_span( ctx
, n
, x
, y
, rgba
, mask
);
549 /* Color component masking */
550 if (colorMask
== 0x0) {
553 else if (colorMask
!= 0xffffffff) {
554 _mesa_mask_rgba_span( ctx
, n
, x
, y
, rgba
);
558 (*swrast
->Driver
.WriteRGBASpan
)( ctx
, n
, x
, y
,
559 (const GLchan (*)[4]) rgba
,
560 write_all
? ((const GLubyte
*) NULL
) : mask
);
562 if (swrast
->_RasterMask
& ALPHABUF_BIT
) {
563 _mesa_write_alpha_span( ctx
, n
, x
, y
,
564 (const GLchan (*)[4]) rgba
,
565 write_all
? ((const GLubyte
*) NULL
) : mask
);
572 * Write a horizontal span of color index pixels to the frame buffer.
573 * Stenciling, Depth-testing, etc. are done as needed.
574 * Input: primitive - either GL_POINT, GL_LINE, GL_POLYGON, or GL_BITMAP
577 _mesa_write_index_span( GLcontext
*ctx
, struct sw_span
*span
,
580 const GLuint modBits
= FOG_BIT
| BLEND_BIT
| MASKING_BIT
| LOGIC_OP_BIT
;
581 GLuint indexBackup
[MAX_WIDTH
];
582 GLuint
*index
; /* points to indexIn or indexBackup */
583 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
586 SET_MASK_TO_ONE(span
);
588 if ((swrast
->_RasterMask
& WINCLIP_BIT
) || primitive
==GL_BITMAP
) {
589 if (clip_span(ctx
,span
) == GL_FALSE
) {
594 if ((primitive
==GL_BITMAP
&& (swrast
->_RasterMask
& modBits
))
595 || (swrast
->_RasterMask
& MULTI_DRAW_BIT
)) {
596 /* Make copy of color indexes */
597 MEMCPY( indexBackup
, span
->color
.index
, span
->end
* sizeof(GLuint
) );
601 index
= span
->color
.index
;
605 /* Do the scissor test */
606 if (ctx
->Scissor
.Enabled
) {
607 if (_mesa_scissor_span( ctx
, span
) == GL_FALSE
) {
612 /* Polygon Stippling */
613 if (ctx
->Polygon
.StippleFlag
&& primitive
==GL_POLYGON
) {
614 stipple_polygon_span(ctx
, span
);
618 /* I have to think where to put this!! */
619 if (span
->activeMask
& SPAN_Z
) {
620 SW_SPAN_SET_FLAG(span
->filledDepth
);
622 if (ctx
->Visual
.depthBits
<= 16) {
624 GLfixed zval
= span
->z
;
625 for (i
= 0; i
< span
->end
; i
++) {
626 span
->depth
[i
] = FixedToInt(zval
);
631 /* Deep Z buffer, no fixed->int shift */
633 GLfixed zval
= span
->z
;
634 for (i
= 0; i
< span
->end
; i
++) {
635 span
->depth
[i
] = zval
;
642 if (ctx
->Stencil
.Enabled
) {
643 /* first stencil test */
644 if (_mesa_stencil_and_ztest_span(ctx
, span
) == GL_FALSE
)
647 else if (ctx
->Depth
.Test
) {
648 /* regular depth testing */
649 if (_mesa_depth_test_span(ctx
, span
) == 0)
653 /* if we get here, something passed the depth test */
654 ctx
->OcclusionResult
= GL_TRUE
;
656 if (ctx
->Color
.DrawBuffer
== GL_NONE
) {
657 /* write no pixels */
661 if (ctx
->Fog
.Enabled
) {
662 /* Is this the right 'if' ?? */
663 if ((span
->activeMask
& SPAN_FOG
) && !swrast
->_PreferPixelFog
)
664 _mesa_fog_ci_pixels( ctx
, span
, index
);
666 _mesa_depth_fog_ci_pixels( ctx
, span
, index
);
669 /* Antialias coverage application */
671 if (span
->coverage
) {
673 for (i
= 0; i
< span
->end
; i
++) {
674 ASSERT(span
->coverage
[i
] < 16);
675 index
[i
] = (index
[i
] & ~0xf) | span
->coverage
[i
];
680 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
681 /* draw to zero or two or more buffers */
682 multi_write_index_span( ctx
, span
->end
, span
->x
, span
->y
,
686 /* normal situation: draw to exactly one buffer */
687 if (ctx
->Color
.IndexLogicOpEnabled
) {
688 _mesa_logicop_ci_span( ctx
, span
->end
, span
->x
, span
->y
,
692 if (ctx
->Color
.IndexMask
== 0) {
695 else if (ctx
->Color
.IndexMask
!= 0xffffffff) {
696 _mesa_mask_index_span( ctx
, span
->end
, span
->x
, span
->y
, index
);
700 (*swrast
->Driver
.WriteCI32Span
)( ctx
, span
->end
, span
->x
,
701 span
->y
, index
, span
->mask
);
709 _mesa_write_monoindex_span( GLcontext
*ctx
, struct sw_span
*span
,
710 GLuint index
, GLenum primitive
)
712 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
716 SET_MASK_TO_ONE(span
);
718 if ((swrast
->_RasterMask
& WINCLIP_BIT
) || primitive
==GL_BITMAP
) {
719 if (clip_span(ctx
,span
) == GL_FALSE
) {
724 /* Do the scissor test */
725 if (ctx
->Scissor
.Enabled
) {
726 if (_mesa_scissor_span( ctx
, span
) == GL_FALSE
) {
731 /* Polygon Stippling */
732 if (ctx
->Polygon
.StippleFlag
&& primitive
==GL_POLYGON
) {
733 stipple_polygon_span( ctx
, span
);
737 /* I have to think where to put this!! */
738 if (span
->activeMask
& SPAN_Z
) {
739 SW_SPAN_SET_FLAG(span
->filledDepth
);
741 if (ctx
->Visual
.depthBits
<= 16) {
743 GLfixed zval
= span
->z
;
744 for (i
= 0; i
< span
->end
; i
++) {
745 span
->depth
[i
] = FixedToInt(zval
);
750 /* Deep Z buffer, no fixed->int shift */
752 GLfixed zval
= span
->z
;
753 for (i
= 0; i
< span
->end
; i
++) {
754 span
->depth
[i
] = zval
;
760 if (ctx
->Stencil
.Enabled
) {
761 /* first stencil test */
762 if (_mesa_stencil_and_ztest_span(ctx
, span
) == GL_FALSE
)
765 else if (ctx
->Depth
.Test
) {
766 /* regular depth testing */
767 if (_mesa_depth_test_span( ctx
, span
) == 0)
771 /* if we get here, something passed the depth test */
772 ctx
->OcclusionResult
= GL_TRUE
;
774 if (ctx
->Color
.DrawBuffer
== GL_NONE
) {
775 /* write no pixels */
780 || ctx
->Color
.IndexLogicOpEnabled
781 || ctx
->Color
.IndexMask
!= 0xffffffff
787 /* different index per pixel */
788 GLuint indexes
[MAX_WIDTH
];
789 for (i
= 0; i
< span
->end
; i
++) {
793 if (ctx
->Fog
.Enabled
) {
794 /* Is this the right 'if' ?? */
795 if ((span
->activeMask
& SPAN_FOG
) && !swrast
->_PreferPixelFog
)
796 _mesa_fog_ci_pixels( ctx
, span
, indexes
);
798 _mesa_depth_fog_ci_pixels( ctx
, span
, indexes
);
801 /* Antialias coverage application */
803 if (span
->coverage
) {
805 for (i
= 0; i
< span
->end
; i
++) {
806 ASSERT(span
->coverage
[i
] < 16);
807 indexes
[i
] = (indexes
[i
] & ~0xf) | span
->coverage
[i
];
812 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
813 /* draw to zero or two or more buffers */
814 multi_write_index_span( ctx
, span
->end
, span
->x
, span
->y
, indexes
, span
->mask
);
817 /* normal situation: draw to exactly one buffer */
818 if (ctx
->Color
.IndexLogicOpEnabled
) {
819 _mesa_logicop_ci_span( ctx
, span
->end
, span
->x
, span
->y
, indexes
, span
->mask
);
821 if (ctx
->Color
.IndexMask
== 0) {
824 else if (ctx
->Color
.IndexMask
!= 0xffffffff) {
825 _mesa_mask_index_span( ctx
, span
->end
, span
->x
, span
->y
, indexes
);
827 (*swrast
->Driver
.WriteCI32Span
)( ctx
, span
->end
, span
->x
, span
->y
, indexes
, span
->mask
);
831 /* same color index for all pixels */
832 ASSERT(!ctx
->Color
.IndexLogicOpEnabled
);
833 ASSERT(ctx
->Color
.IndexMask
== 0xffffffff);
834 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
835 /* draw to zero or two or more buffers */
836 GLuint indexes
[MAX_WIDTH
];
837 for (i
= 0; i
< span
->end
; i
++)
839 multi_write_index_span( ctx
, span
->end
, span
->x
, span
->y
, indexes
, span
->mask
);
842 /* normal situation: draw to exactly one buffer */
843 (*swrast
->Driver
.WriteMonoCISpan
)( ctx
, span
->end
, span
->x
, span
->y
, index
, span
->mask
);
851 * Apply fragment processing to a span of RGBA fragments.
855 _mesa_write_rgba_span( GLcontext
*ctx
, struct sw_span
*span
,
858 const GLuint modBits
= FOG_BIT
| BLEND_BIT
| MASKING_BIT
|
859 LOGIC_OP_BIT
| TEXTURE_BIT
;
860 GLchan rgbaBackup
[MAX_WIDTH
][4];
862 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
865 SET_MASK_TO_ONE(span
);
867 if ((swrast
->_RasterMask
& WINCLIP_BIT
) || primitive
==GL_BITMAP
) {
868 if (clip_span( ctx
,span
) == GL_FALSE
) {
874 /* Do the scissor test */
875 if (ctx
->Scissor
.Enabled
) {
876 if (_mesa_scissor_span( ctx
, span
) == GL_FALSE
) {
882 /* Polygon Stippling */
883 if (ctx
->Polygon
.StippleFlag
&& primitive
==GL_POLYGON
) {
884 stipple_polygon_span( ctx
, span
);
888 if ((primitive
==GL_BITMAP
&& (swrast
->_RasterMask
& modBits
))
889 || (swrast
->_RasterMask
& MULTI_DRAW_BIT
)) {
890 /* must make a copy of the colors since they may be modified */
891 MEMCPY( rgbaBackup
, span
->color
.rgba
, 4 * span
->end
* sizeof(GLchan
) );
895 rgba
= span
->color
.rgba
;
899 /* Do the alpha test */
900 if (ctx
->Color
.AlphaEnabled
) {
901 if (_mesa_alpha_test( ctx
, span
->end
, (const GLchan (*)[4]) rgba
, span
->mask
) == 0) {
904 span
->write_all
= GL_FALSE
;
907 /* I have to think where to put this!! */
908 if (span
->activeMask
& SPAN_Z
) {
909 SW_SPAN_SET_FLAG(span
->filledDepth
);
911 if (ctx
->Visual
.depthBits
<= 16) {
913 GLfixed zval
= span
->z
;
914 for (i
= 0; i
< span
->end
; i
++) {
915 span
->depth
[i
] = FixedToInt(zval
);
920 /* Deep Z buffer, no fixed->int shift */
922 GLfixed zval
= span
->z
;
923 for (i
= 0; i
< span
->end
; i
++) {
924 span
->depth
[i
] = zval
;
930 if (ctx
->Stencil
.Enabled
) {
931 /* first stencil test */
932 if (_mesa_stencil_and_ztest_span(ctx
, span
) == GL_FALSE
)
935 else if (ctx
->Depth
.Test
) {
936 /* regular depth testing */
937 if (_mesa_depth_test_span(ctx
, span
) == GL_FALSE
)
941 /* if we get here, something passed the depth test */
942 ctx
->OcclusionResult
= GL_TRUE
;
945 if (ctx
->Fog
.Enabled
) {
946 /* Is this the right 'if' ?? */
947 if ((span
->activeMask
& SPAN_FOG
) && !swrast
->_PreferPixelFog
)
948 _mesa_fog_rgba_pixels( ctx
, span
, rgba
);
950 _mesa_depth_fog_rgba_pixels( ctx
, span
, rgba
);
953 /* Antialias coverage application */
955 if (span
->coverage
) {
957 for (i
= 0; i
< span
->end
; i
++) {
958 rgba
[i
][ACOMP
] = (GLchan
) (rgba
[i
][ACOMP
] * span
->coverage
[i
]);
963 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
964 multi_write_rgba_span( ctx
, span
->end
, span
->x
, span
->y
, (const GLchan (*)[4]) rgba
, span
->mask
);
967 /* normal: write to exactly one buffer */
968 /* logic op or blending */
969 const GLuint colorMask
= *((GLuint
*) ctx
->Color
.ColorMask
);
971 if (ctx
->Color
.ColorLogicOpEnabled
) {
972 _mesa_logicop_rgba_span( ctx
, span
->end
, span
->x
, span
->y
, rgba
, span
->mask
);
974 else if (ctx
->Color
.BlendEnabled
) {
975 _mesa_blend_span( ctx
, span
->end
, span
->x
, span
->y
, rgba
, span
->mask
);
978 /* Color component masking */
979 if (colorMask
== 0x0) {
982 else if (colorMask
!= 0xffffffff) {
983 _mesa_mask_rgba_span( ctx
, span
->end
, span
->x
, span
->y
, rgba
);
987 (*swrast
->Driver
.WriteRGBASpan
)( ctx
, span
->end
, span
->x
, span
->y
,
988 (const GLchan (*)[4]) rgba
,
989 span
->write_all
? ((const GLubyte
*) NULL
) : span
->mask
);
991 if (swrast
->_RasterMask
& ALPHABUF_BIT
) {
992 _mesa_write_alpha_span( ctx
, span
->end
, span
->x
, span
->y
,
993 (const GLchan (*)[4]) rgba
,
994 span
->write_all
? ((const GLubyte
*) NULL
) : span
->mask
);
1001 * Write a horizontal span of color pixels to the frame buffer.
1002 * The color is initially constant for the whole span.
1003 * Alpha-testing, stenciling, depth-testing, and blending are done as needed.
1004 * Input: r, g, b, a - the color of the pixels
1005 * primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP.
1008 _mesa_write_monocolor_span( GLcontext
*ctx
, struct sw_span
*span
,
1009 const GLchan color
[4], GLenum primitive
)
1011 const GLuint colorMask
= *((GLuint
*) ctx
->Color
.ColorMask
);
1013 GLchan rgba
[MAX_WIDTH
][4];
1014 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1017 SET_MASK_TO_ONE(span
);
1019 if ((swrast
->_RasterMask
& WINCLIP_BIT
) || primitive
==GL_BITMAP
) {
1020 if (clip_span(ctx
,span
) == GL_FALSE
) {
1025 /* Do the scissor test */
1026 if (ctx
->Scissor
.Enabled
) {
1027 if (_mesa_scissor_span( ctx
, span
) == GL_FALSE
) {
1032 /* Polygon Stippling */
1033 if (ctx
->Polygon
.StippleFlag
&& primitive
==GL_POLYGON
) {
1034 stipple_polygon_span( ctx
, span
);
1037 /* Do the alpha test */
1038 if (ctx
->Color
.AlphaEnabled
) {
1039 for (i
= 0; i
< span
->end
; i
++) {
1040 rgba
[i
][ACOMP
] = color
[ACOMP
];
1042 if (_mesa_alpha_test( ctx
, span
->end
, (const GLchan (*)[4])rgba
, span
->mask
) == 0) {
1045 span
->write_all
= GL_FALSE
;
1048 /* I have to think where to put this!! */
1049 if (span
->activeMask
& SPAN_Z
) {
1050 SW_SPAN_SET_FLAG(span
->filledDepth
);
1052 if (ctx
->Visual
.depthBits
<= 16) {
1054 GLfixed zval
= span
->z
;
1055 for (i
= 0; i
< span
->end
; i
++) {
1056 span
->depth
[i
] = FixedToInt(zval
);
1057 zval
+= span
->zStep
;
1061 /* Deep Z buffer, no fixed->int shift */
1063 GLfixed zval
= span
->z
;
1064 for (i
= 0; i
< span
->end
; i
++) {
1065 span
->depth
[i
] = zval
;
1066 zval
+= span
->zStep
;
1071 if (ctx
->Stencil
.Enabled
) {
1072 /* first stencil test */
1073 if (_mesa_stencil_and_ztest_span(ctx
, span
) == GL_FALSE
)
1076 else if (ctx
->Depth
.Test
) {
1077 /* regular depth testing */
1078 if (_mesa_depth_test_span(ctx
, span
) == 0)
1082 /* if we get here, something passed the depth test */
1083 ctx
->OcclusionResult
= GL_TRUE
;
1085 if (ctx
->Color
.DrawBuffer
== GL_NONE
) {
1086 /* write no pixels */
1090 if (ctx
->Color
.ColorLogicOpEnabled
|| colorMask
!= 0xffffffff ||
1092 (swrast
->_RasterMask
& (BLEND_BIT
| FOG_BIT
)) || coverage
) {
1094 (swrast
->_RasterMask
& (BLEND_BIT
| FOG_BIT
))) {
1096 /* assign same color to each pixel */
1097 SW_SPAN_SET_FLAG(span
->filledColor
);
1098 for (i
= 0; i
< span
->end
; i
++) {
1099 if (span
->mask
[i
]) {
1100 COPY_CHAN4(rgba
[i
], color
);
1105 if (ctx
->Fog
.Enabled
) {
1106 /* Is this the right 'if' ?? */
1107 if ((span
->activeMask
& SPAN_FOG
) && !swrast
->_PreferPixelFog
)
1108 _mesa_fog_rgba_pixels( ctx
, span
, rgba
);
1110 _mesa_depth_fog_rgba_pixels( ctx
, span
, rgba
);
1113 /* Antialias coverage application */
1115 if (span
->coverage
) {
1117 for (i
= 0; i
< span
->end
; i
++) {
1118 rgba
[i
][ACOMP
] = (GLchan
) (rgba
[i
][ACOMP
] * span
->coverage
[i
]);
1123 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
1124 multi_write_rgba_span( ctx
, span
->end
, span
->x
, span
->y
,
1125 (const GLchan (*)[4]) rgba
, span
->mask
);
1128 /* normal: write to exactly one buffer */
1129 if (ctx
->Color
.ColorLogicOpEnabled
) {
1130 _mesa_logicop_rgba_span( ctx
, span
->end
, span
->x
, span
->y
, rgba
, span
->mask
);
1132 else if (ctx
->Color
.BlendEnabled
) {
1133 _mesa_blend_span( ctx
, span
->end
, span
->x
, span
->y
, rgba
, span
->mask
);
1136 /* Color component masking */
1137 if (colorMask
== 0x0) {
1140 else if (colorMask
!= 0xffffffff) {
1141 _mesa_mask_rgba_span( ctx
, span
->end
, span
->x
, span
->y
, rgba
);
1145 (*swrast
->Driver
.WriteRGBASpan
)( ctx
, span
->end
, span
->x
, span
->y
,
1146 (const GLchan (*)[4]) rgba
,
1147 span
->write_all
? ((const GLubyte
*) NULL
) : span
->mask
);
1148 if (swrast
->_RasterMask
& ALPHABUF_BIT
) {
1149 _mesa_write_alpha_span( ctx
, span
->end
, span
->x
, span
->y
,
1150 (const GLchan (*)[4]) rgba
,
1151 span
->write_all
? ((const GLubyte
*) NULL
) : span
->mask
);
1156 /* same color for all pixels */
1157 ASSERT(!ctx
->Color
.BlendEnabled
);
1158 ASSERT(!ctx
->Color
.ColorLogicOpEnabled
);
1160 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
1161 SW_SPAN_SET_FLAG(span
->filledColor
);
1162 for (i
= 0; i
< span
->end
; i
++) {
1163 if (span
->mask
[i
]) {
1164 COPY_CHAN4(rgba
[i
], color
);
1167 multi_write_rgba_span( ctx
, span
->end
, span
->x
, span
->y
,
1168 (const GLchan (*)[4]) rgba
, span
->mask
);
1171 (*swrast
->Driver
.WriteMonoRGBASpan
)( ctx
, span
->end
, span
->x
, span
->y
, color
, span
->mask
);
1172 if (swrast
->_RasterMask
& ALPHABUF_BIT
) {
1173 _mesa_write_mono_alpha_span( ctx
, span
->end
, span
->x
, span
->y
, (GLchan
) color
[ACOMP
],
1174 span
->write_all
? ((const GLubyte
*) NULL
) : span
->mask
);
1183 * Add specular color to base color. This is used only when
1184 * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
1187 add_colors(CONST
struct sw_span
*span
, GLchan rgba
[][4])
1190 ASSERT(span
->filledSpecular
== GL_TRUE
);
1191 ASSERT(span
->filledColor
== GL_TRUE
);
1193 for (i
= 0; i
< span
->end
; i
++) {
1194 #if CHAN_TYPE == GL_FLOAT
1196 rgba
[i
][RCOMP
] += span
->specular
[i
][RCOMP
];
1197 rgba
[i
][GCOMP
] += span
->specular
[i
][GCOMP
];
1198 rgba
[i
][BCOMP
] += span
->specular
[i
][BCOMP
];
1200 GLint r
= rgba
[i
][RCOMP
] + span
->specular
[i
][RCOMP
];
1201 GLint g
= rgba
[i
][GCOMP
] + span
->specular
[i
][GCOMP
];
1202 GLint b
= rgba
[i
][BCOMP
] + span
->specular
[i
][BCOMP
];
1203 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
1204 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
1205 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
1212 * Write a horizontal span of textured pixels to the frame buffer.
1213 * The color of each pixel is different.
1214 * Depth-testing, stenciling, scissor-testing etc. should already
1216 * only if alpha-testing is used, depth-testing is still done in this
1218 * Input: n - number of pixels in the span
1219 * x, y - location of leftmost pixel in the span
1220 * z - array of [n] z-values
1221 * s, t - array of (s,t) texture coordinates for each pixel
1222 * lambda - array of texture lambda values
1223 * rgba - array of [n] color components
1224 * mask - masked pixels
1225 * primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP.
1226 * Contributed by Klaus Niederkrueger.
1229 masked_texture_span( GLcontext
*ctx
, struct sw_span
*span
)
1231 const GLuint colorMask
= *((GLuint
*) ctx
->Color
.ColorMask
);
1232 GLchan rgbaBackup
[MAX_WIDTH
][4];
1233 GLchan (*rgba
)[4]; /* points to either span->color.rgba or rgbaBackup */
1234 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1237 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
1238 /* must make a copy of the colors since they may be modified */
1239 MEMCPY(rgbaBackup
, span
->color
.rgba
, 4 * span
->end
* sizeof(GLchan
));
1243 rgba
= span
->color
.rgba
;
1247 ASSERT(ctx
->Texture
._ReallyEnabled
);
1248 _swrast_texture_fragments( ctx
, 0, span
, rgba
);
1251 /* Texture with alpha test */
1252 if (ctx
->Color
.AlphaEnabled
) {
1253 /* Do the alpha test */
1254 if (_mesa_alpha_test( ctx
, span
->end
, (const GLchan (*)[4]) rgba
, span
->mask
) == 0) {
1257 span
->write_all
= GL_FALSE
;
1259 /* Depth test usually in 'rasterize_span' but if alpha test
1260 needed, we have to wait for that test before depth test can
1262 if (ctx
->Stencil
.Enabled
) {
1263 /* first stencil test */
1264 if (_mesa_stencil_and_ztest_span(ctx
, span
) == GL_FALSE
)
1267 else if (ctx
->Depth
.Test
) {
1268 /* regular depth testing */
1269 if (_mesa_depth_test_span(ctx
, span
) == 0)
1274 /* if we get here, something passed the depth test */
1275 ctx
->OcclusionResult
= GL_TRUE
;
1278 /* Add base and specular colors */
1279 if ((span
->activeMask
& SPAN_SPEC
) && /* Is this right test ???*/
1280 (ctx
->Fog
.ColorSumEnabled
||
1281 (ctx
->Light
.Enabled
&&
1282 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
)))
1283 add_colors(span
, rgba
); /* rgba = rgba + spec */
1286 if (ctx
->Fog
.Enabled
) {
1287 /* Is this the right 'if' ?? */
1288 if ((span
->activeMask
& SPAN_FOG
) && !swrast
->_PreferPixelFog
)
1289 _mesa_fog_rgba_pixels(ctx
, span
, rgba
);
1291 _mesa_depth_fog_rgba_pixels(ctx
, span
, rgba
);
1294 /* Antialias coverage application */
1296 if (span
->coverage
) {
1298 for (i
= 0; i
< span
->end
; i
++) {
1299 rgba
[i
][ACOMP
] = (GLchan
) (rgba
[i
][ACOMP
] * span
->coverage
[i
]);
1304 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
1305 multi_write_rgba_span( ctx
, span
->end
, span
->x
, span
->y
, (const GLchan (*)[4]) rgba
, span
->mask
);
1308 /* normal: write to exactly one buffer */
1309 if (ctx
->Color
.ColorLogicOpEnabled
) {
1310 _mesa_logicop_rgba_span( ctx
, span
->end
, span
->x
, span
->y
, rgba
, span
->mask
);
1312 else if (ctx
->Color
.BlendEnabled
) {
1313 _mesa_blend_span( ctx
, span
->end
, span
->x
, span
->y
, rgba
, span
->mask
);
1315 if (colorMask
== 0x0) {
1318 else if (colorMask
!= 0xffffffff) {
1319 _mesa_mask_rgba_span( ctx
, span
->end
, span
->x
, span
->y
, rgba
);
1322 (*swrast
->Driver
.WriteRGBASpan
)( ctx
, span
->end
, span
->x
, span
->y
, (const GLchan (*)[4])rgba
,
1323 span
->write_all
? NULL
: span
->mask
);
1324 if (swrast
->_RasterMask
& ALPHABUF_BIT
) {
1325 _mesa_write_alpha_span( ctx
, span
->end
, span
->x
, span
->y
, (const GLchan (*)[4]) rgba
,
1326 span
->write_all
? NULL
: span
->mask
);
1333 * As above but perform multiple stages of texture application.
1334 * Contributed by Klaus Niederkrueger.
1337 masked_multitexture_span( GLcontext
*ctx
, struct sw_span
*span
)
1339 GLchan rgbaBackup
[MAX_WIDTH
][4];
1340 GLchan (*rgba
)[4]; /* points to either span->color.rgba or rgbaBackup */
1342 const GLuint texUnits
= ctx
->Const
.MaxTextureUnits
;
1343 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1346 if ( (swrast
->_RasterMask
& MULTI_DRAW_BIT
) || texUnits
> 1) {
1347 /* must make a copy of the colors since they may be modified */
1348 MEMCPY(rgbaBackup
, span
->color
.rgba
, 4 * span
->end
* sizeof(GLchan
));
1352 rgba
= span
->color
.rgba
;
1356 ASSERT(ctx
->Texture
._ReallyEnabled
);
1357 for (i
= 0; i
< texUnits
; i
++)
1358 _swrast_texture_fragments( ctx
, i
, span
, rgba
);
1360 /* Texture with alpha test */
1361 if (ctx
->Color
.AlphaEnabled
) {
1362 /* Do the alpha test */
1363 if (_mesa_alpha_test( ctx
, span
->end
, (const GLchan (*)[4])rgba
, span
->mask
) == 0) {
1366 span
->write_all
= GL_FALSE
;
1367 /* Depth test usually in 'rasterize_span' but if alpha test
1368 needed, we have to wait for that test before depth test can
1370 if (ctx
->Stencil
.Enabled
) {
1371 /* first stencil test */
1372 if (_mesa_stencil_and_ztest_span(ctx
, span
) == GL_FALSE
)
1375 else if (ctx
->Depth
.Test
) {
1376 /* regular depth testing */
1377 if (_mesa_depth_test_span(ctx
, span
) == GL_FALSE
)
1382 /* if we get here, something passed the depth test */
1383 ctx
->OcclusionResult
= GL_TRUE
;
1386 /* Add base and specular colors */
1387 if ((span
->activeMask
& SPAN_SPEC
) && /* Is this right test ???*/
1388 (ctx
->Fog
.ColorSumEnabled
||
1389 (ctx
->Light
.Enabled
&&
1390 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
)))
1391 add_colors(span
, rgba
); /* rgba = rgba + spec */
1394 if (ctx
->Fog
.Enabled
) {
1395 /* Is this the right 'if' ?? */
1396 if ((span
->activeMask
& SPAN_FOG
) && !swrast
->_PreferPixelFog
)
1397 _mesa_fog_rgba_pixels( ctx
, span
, rgba
);
1399 _mesa_depth_fog_rgba_pixels( ctx
, span
, rgba
);
1402 /* Antialias coverage application */
1404 if (span
->coverage
) {
1406 for (i
= 0; i
< span
->end
; i
++) {
1407 rgba
[i
][ACOMP
] = (GLchan
) (rgba
[i
][ACOMP
] * span
->coverage
[i
]);
1412 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
1413 multi_write_rgba_span( ctx
, span
->end
, span
->x
, span
->y
, (const GLchan (*)[4]) rgba
, span
->mask
);
1416 /* normal: write to exactly one buffer */
1417 const GLuint colorMask
= *((GLuint
*) ctx
->Color
.ColorMask
);
1419 if (ctx
->Color
.ColorLogicOpEnabled
) {
1420 _mesa_logicop_rgba_span( ctx
, span
->end
, span
->x
, span
->y
, rgba
, span
->mask
);
1422 else if (ctx
->Color
.BlendEnabled
) {
1423 _mesa_blend_span( ctx
, span
->end
, span
->x
, span
->y
, rgba
, span
->mask
);
1426 if (colorMask
== 0x0) {
1429 else if (colorMask
!= 0xffffffff) {
1430 _mesa_mask_rgba_span( ctx
, span
->end
, span
->x
, span
->y
, rgba
);
1433 (*swrast
->Driver
.WriteRGBASpan
)( ctx
, span
->end
, span
->x
, span
->y
, (const GLchan (*)[4])rgba
,
1434 span
->write_all
? NULL
: span
->mask
);
1435 if (swrast
->_RasterMask
& ALPHABUF_BIT
) {
1436 _mesa_write_alpha_span( ctx
, span
->end
, span
->x
, span
->y
, (const GLchan (*)[4])rgba
,
1437 span
->write_all
? NULL
: span
->mask
);
1444 * Generate arrays of fragment colors, z, fog, texcoords, etc from a
1445 * triangle span object. Then call the span/fragment processsing
1446 * functions in s_span.[ch]. This is used by a bunch of the textured
1447 * triangle functions.
1448 * Contributed by Klaus Niederkrueger.
1451 _mesa_rasterize_span(GLcontext
*ctx
, struct sw_span
*span
)
1453 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1455 SET_MASK_TO_ONE(span
);
1458 if (swrast
->_RasterMask
& WINCLIP_BIT
) {
1459 if (clip_span(ctx
, span
) == GL_FALSE
) {
1464 /* Do the scissor test */
1465 if (ctx
->Scissor
.Enabled
) {
1466 if (_mesa_scissor_span( ctx
, span
) == GL_FALSE
) {
1471 /* Polygon Stippling */
1472 if (ctx
->Polygon
.StippleFlag
) {
1473 stipple_polygon_span( ctx
, span
);
1476 /* I have to think where to put this!! */
1477 if (span
->activeMask
& SPAN_Z
) {
1478 SW_SPAN_SET_FLAG(span
->filledDepth
);
1480 if (ctx
->Visual
.depthBits
<= 16) {
1482 GLfixed zval
= span
->z
;
1483 for (i
= 0; i
< span
->end
; i
++) {
1484 span
->depth
[i
] = FixedToInt(zval
);
1485 zval
+= span
->zStep
;
1489 /* Deep Z buffer, no fixed->int shift */
1491 GLfixed zval
= span
->z
;
1492 for (i
= 0; i
< span
->end
; i
++) {
1493 span
->depth
[i
] = zval
;
1494 zval
+= span
->zStep
;
1499 /* Correct order: texturing --> alpha test --> depth test. But if
1500 no alpha test needed, we can do here the depth test and
1501 potentially avoid some of the texturing (otherwise alpha test,
1502 depth test etc. happens in masked_texture_span(). */
1503 if (span
->activeMask
& SPAN_Z
&& !ctx
->Color
.AlphaEnabled
) {
1504 if (ctx
->Stencil
.Enabled
) {
1505 /* first stencil test */
1506 if (_mesa_stencil_and_ztest_span(ctx
, span
) == GL_FALSE
)
1509 else if (ctx
->Depth
.Test
) {
1510 /* regular depth testing */
1511 if (_mesa_depth_test_span( ctx
, span
) == 0) {
1517 if (span
->activeMask
& SPAN_RGBA
) {
1518 ASSERT(span
->filledColor
== GL_FALSE
);
1519 SW_SPAN_SET_FLAG(span
->filledColor
);
1520 if (span
->activeMask
& SPAN_FLAT
) {
1523 color
[RCOMP
] = FixedToChan(span
->red
);
1524 color
[GCOMP
] = FixedToChan(span
->green
);
1525 color
[BCOMP
] = FixedToChan(span
->blue
);
1526 color
[ACOMP
] = FixedToChan(span
->alpha
);
1527 for (i
= 0; i
< span
->end
; i
++) {
1528 COPY_CHAN4(span
->color
.rgba
[i
], color
);
1532 /* smooth interpolation */
1533 #if CHAN_TYPE == GL_FLOAT
1534 GLfloat r
= span
->red
;
1535 GLfloat g
= span
->green
;
1536 GLfloat b
= span
->blue
;
1537 GLfloat a
= span
->alpha
;
1539 GLfixed r
= span
->red
;
1540 GLfixed g
= span
->green
;
1541 GLfixed b
= span
->blue
;
1542 GLfixed a
= span
->alpha
;
1545 for (i
= 0; i
< span
->end
; i
++) {
1546 span
->color
.rgba
[i
][RCOMP
] = FixedToChan(r
);
1547 span
->color
.rgba
[i
][GCOMP
] = FixedToChan(g
);
1548 span
->color
.rgba
[i
][BCOMP
] = FixedToChan(b
);
1549 span
->color
.rgba
[i
][ACOMP
] = FixedToChan(a
);
1551 g
+= span
->greenStep
;
1552 b
+= span
->blueStep
;
1553 a
+= span
->alphaStep
;
1558 if (span
->activeMask
& SPAN_SPEC
) {
1559 SW_SPAN_SET_FLAG(span
->filledSpecular
);
1560 if (span
->activeMask
& SPAN_FLAT
) {
1561 const GLchan r
= FixedToChan(span
->specRed
);
1562 const GLchan g
= FixedToChan(span
->specGreen
);
1563 const GLchan b
= FixedToChan(span
->specBlue
);
1565 for (i
= 0; i
< span
->end
; i
++) {
1566 span
->specular
[i
][RCOMP
] = r
;
1567 span
->specular
[i
][GCOMP
] = g
;
1568 span
->specular
[i
][BCOMP
] = b
;
1572 /* smooth interpolation */
1573 #if CHAN_TYPE == GL_FLOAT
1574 GLfloat r
= span
->specRed
;
1575 GLfloat g
= span
->specGreen
;
1576 GLfloat b
= span
->specBlue
;
1578 GLfixed r
= span
->specRed
;
1579 GLfixed g
= span
->specGreen
;
1580 GLfixed b
= span
->specBlue
;
1583 for (i
= 0; i
< span
->end
; i
++) {
1584 span
->specular
[i
][RCOMP
] = FixedToChan(r
);
1585 span
->specular
[i
][GCOMP
] = FixedToChan(g
);
1586 span
->specular
[i
][BCOMP
] = FixedToChan(b
);
1587 r
+= span
->specRedStep
;
1588 g
+= span
->specGreenStep
;
1589 b
+= span
->specBlueStep
;
1594 if (span
->activeMask
& SPAN_INDEX
) {
1595 SW_SPAN_SET_FLAG(span
->filledColor
);
1596 if (span
->activeMask
& SPAN_FLAT
) {
1598 const GLint indx
= FixedToInt(span
->index
);
1599 for (i
= 0; i
< span
->end
; i
++) {
1600 span
->color
.index
[i
] = indx
;
1604 /* smooth interpolation */
1606 GLfixed ind
= span
->index
;
1607 for (i
= 0; i
< span
->end
; i
++) {
1608 span
->color
.index
[i
] = FixedToInt(ind
);
1609 ind
+= span
->indexStep
;
1614 if (span
->activeMask
& SPAN_TEXTURE
) {
1615 if (ctx
->Texture
._ReallyEnabled
& ~TEXTURE0_ANY
) {
1617 if (span
->activeMask
& SPAN_LAMBDA
) {
1620 /* multitexture, lambda */
1621 for (u
= 0; u
< MAX_TEXTURE_UNITS
; u
++) {
1622 if (ctx
->Texture
.Unit
[u
]._ReallyEnabled
) {
1623 GLfloat s
= span
->tex
[u
][0];
1624 GLfloat t
= span
->tex
[u
][1];
1625 GLfloat r
= span
->tex
[u
][2];
1626 GLfloat q
= span
->tex
[u
][3];
1628 SW_SPAN_SET_FLAG(span
->filledLambda
[u
]);
1629 SW_SPAN_SET_FLAG(span
->filledTex
[u
]);
1630 for (i
= 0; i
< span
->end
; i
++) {
1631 const GLfloat invQ
= (q
== 0.0F
) ? 1.0F
: (1.0F
/ q
);
1632 span
->texcoords
[u
][i
][0] = s
* invQ
;
1633 span
->texcoords
[u
][i
][1] = t
* invQ
;
1634 span
->texcoords
[u
][i
][2] = r
* invQ
;
1635 span
->lambda
[u
][i
] = (GLfloat
)
1636 (log(span
->rho
[u
] * invQ
* invQ
) * 1.442695F
* 0.5F
);
1637 s
+= span
->texStep
[u
][0];
1638 t
+= span
->texStep
[u
][1];
1639 r
+= span
->texStep
[u
][2];
1640 q
+= span
->texStep
[u
][3];
1646 /* without lambda */
1648 /* multitexture, no lambda */
1649 for (u
= 0; u
< MAX_TEXTURE_UNITS
; u
++) {
1650 if (ctx
->Texture
.Unit
[u
]._ReallyEnabled
) {
1651 GLfloat s
= span
->tex
[u
][0];
1652 GLfloat t
= span
->tex
[u
][1];
1653 GLfloat r
= span
->tex
[u
][2];
1654 GLfloat q
= span
->tex
[u
][3];
1656 SW_SPAN_SET_FLAG(span
->filledTex
[u
]);
1657 for (i
= 0; i
< span
->end
; i
++) {
1658 const GLfloat invQ
= (q
== 0.0F
) ? 1.0F
: (1.0F
/ q
);
1659 span
->texcoords
[u
][i
][0] = s
* invQ
;
1660 span
->texcoords
[u
][i
][1] = t
* invQ
;
1661 span
->texcoords
[u
][i
][2] = r
* invQ
;
1662 s
+= span
->texStep
[u
][0];
1663 t
+= span
->texStep
[u
][1];
1664 r
+= span
->texStep
[u
][2];
1665 q
+= span
->texStep
[u
][3];
1672 /* just texture unit 0 */
1675 for (i
=0; i
<MAX_TEXTURE_UNITS
; i
++) {
1676 ASSERT(span
->filledTex
[i
] == GL_FALSE
&&
1677 span
->filledLambda
[i
] == GL_FALSE
);
1680 if (span
->activeMask
& SPAN_LAMBDA
) {
1682 GLfloat s
= span
->tex
[0][0];
1683 GLfloat t
= span
->tex
[0][1];
1684 GLfloat r
= span
->tex
[0][2];
1685 GLfloat q
= span
->tex
[0][3];
1687 SW_SPAN_SET_FLAG(span
->filledLambda
[0]);
1688 SW_SPAN_SET_FLAG(span
->filledTex
[0]);
1689 /* single texture, lambda */
1690 for (i
= 0; i
< span
->end
; i
++) {
1691 const GLfloat invQ
= (q
== 0.0F
) ? 1.0F
: (1.0F
/ q
);
1692 span
->texcoords
[0][i
][0] = s
* invQ
;
1693 span
->texcoords
[0][i
][1] = t
* invQ
;
1694 span
->texcoords
[0][i
][2] = r
* invQ
;
1695 span
->lambda
[0][i
] = (GLfloat
)
1696 (log(span
->rho
[0] * invQ
* invQ
) * 1.442695F
* 0.5F
);
1697 s
+= span
->texStep
[0][0];
1698 t
+= span
->texStep
[0][1];
1699 r
+= span
->texStep
[0][2];
1700 q
+= span
->texStep
[0][3];
1704 /* without lambda */
1705 GLfloat s
= span
->tex
[0][0];
1706 GLfloat t
= span
->tex
[0][1];
1707 GLfloat r
= span
->tex
[0][2];
1708 GLfloat q
= span
->tex
[0][3];
1710 SW_SPAN_SET_FLAG(span
->filledTex
[0]);
1711 /* single texture, no lambda */
1712 for (i
= 0; i
< span
->end
; i
++) {
1713 const GLfloat invQ
= (q
== 0.0F
) ? 1.0F
: (1.0F
/ q
);
1714 span
->texcoords
[0][i
][0] = s
* invQ
;
1715 span
->texcoords
[0][i
][1] = t
* invQ
;
1716 span
->texcoords
[0][i
][2] = r
* invQ
;
1717 s
+= span
->texStep
[0][0];
1718 t
+= span
->texStep
[0][1];
1719 r
+= span
->texStep
[0][2];
1720 q
+= span
->texStep
[0][3];
1725 /* XXX keep this? */
1726 if (span
->activeMask
& SPAN_INT_TEXTURE
) {
1727 GLfixed s
= span
->intTex
[0];
1728 GLfixed t
= span
->intTex
[1];
1730 for (i
= 0; i
< span
->end
; i
++) {
1731 span
->itexcoords
[i
][0] = FixedToInt(s
);
1732 span
->itexcoords
[i
][1] = FixedToInt(t
);
1733 s
+= span
->intTexStep
[0];
1734 t
+= span
->intTexStep
[1];
1738 /* examine activeMask and call a s_span.c function */
1739 if (span
->activeMask
& SPAN_TEXTURE
) {
1741 if (ctx
->Texture
._ReallyEnabled
& ~TEXTURE0_ANY
) {
1743 masked_multitexture_span(ctx
, span
);
1746 /* single texture */
1747 masked_texture_span(ctx
, span
);
1751 _mesa_problem(ctx
, "rasterize_span() should only be used for texturing");
1757 * Add specular color to base color. This is used only when
1758 * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
1761 _old_add_colors(GLuint n
, GLchan rgba
[][4], GLchan specular
[][4] )
1764 for (i
= 0; i
< n
; i
++) {
1765 #if CHAN_TYPE == GL_FLOAT
1767 rgba
[i
][RCOMP
] += specular
[i
][RCOMP
];
1768 rgba
[i
][GCOMP
] += specular
[i
][GCOMP
];
1769 rgba
[i
][BCOMP
] += specular
[i
][BCOMP
];
1771 GLint r
= rgba
[i
][RCOMP
] + specular
[i
][RCOMP
];
1772 GLint g
= rgba
[i
][GCOMP
] + specular
[i
][GCOMP
];
1773 GLint b
= rgba
[i
][BCOMP
] + specular
[i
][BCOMP
];
1774 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
1775 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
1776 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
1783 * Write a horizontal span of textured pixels to the frame buffer.
1784 * The color of each pixel is different.
1785 * Alpha-testing, stenciling, depth-testing, and blending are done
1787 * Input: n - number of pixels in the span
1788 * x, y - location of leftmost pixel in the span
1789 * z - array of [n] z-values
1790 * fog - array of fog factor values in [0,1]
1791 * s, t - array of (s,t) texture coordinates for each pixel
1792 * lambda - array of texture lambda values
1793 * rgba - array of [n] color components
1794 * primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP.
1797 _old_write_texture_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
1798 const GLdepth z
[], const GLfloat fog
[],
1799 GLfloat texcoord
[][4],
1801 GLchan rgbaIn
[][4], GLchan spec
[][4],
1802 const GLfloat coverage
[], GLenum primitive
)
1804 const GLuint colorMask
= *((GLuint
*) ctx
->Color
.ColorMask
);
1805 GLubyte mask
[MAX_WIDTH
];
1806 GLboolean write_all
= GL_TRUE
;
1807 GLchan rgbaBackup
[MAX_WIDTH
][4];
1808 GLchan (*rgba
)[4]; /* points to either rgbaIn or rgbaBackup */
1809 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1811 /* init mask to 1's (all pixels are to be written) */
1814 if ((swrast
->_RasterMask
& WINCLIP_BIT
) || primitive
==GL_BITMAP
) {
1815 if ((n
=old_clip_span(ctx
, n
, x
, y
, mask
)) == 0) {
1819 write_all
= GL_FALSE
;
1823 if (primitive
==GL_BITMAP
|| (swrast
->_RasterMask
& MULTI_DRAW_BIT
)) {
1824 /* must make a copy of the colors since they may be modified */
1825 MEMCPY(rgbaBackup
, rgbaIn
, 4 * n
* sizeof(GLchan
));
1832 /* Do the scissor test */
1833 if (ctx
->Scissor
.Enabled
) {
1834 if ((n
= _old_scissor_span( ctx
, n
, x
, y
, mask
)) == 0) {
1838 write_all
= GL_FALSE
;
1841 /* Polygon Stippling */
1842 if (ctx
->Polygon
.StippleFlag
&& primitive
==GL_POLYGON
) {
1843 old_stipple_polygon_span( ctx
, n
, x
, y
, mask
);
1844 write_all
= GL_FALSE
;
1847 /* Texture with alpha test */
1848 if (ctx
->Color
.AlphaEnabled
) {
1849 /* Texturing without alpha is done after depth-testing which
1850 gives a potential speed-up. */
1851 ASSERT(ctx
->Texture
._ReallyEnabled
);
1852 _old_swrast_texture_fragments( ctx
, 0, n
, texcoord
, lambda
,
1853 (CONST
GLchan (*)[4]) rgba
, rgba
);
1855 /* Do the alpha test */
1856 if (_mesa_alpha_test( ctx
, n
, (const GLchan (*)[4]) rgba
, mask
) == 0) {
1859 write_all
= GL_FALSE
;
1862 if (ctx
->Stencil
.Enabled
) {
1863 /* first stencil test */
1864 if (_old_stencil_and_ztest_span(ctx
, n
, x
, y
, z
, mask
) == GL_FALSE
) {
1867 write_all
= GL_FALSE
;
1869 else if (ctx
->Depth
.Test
) {
1870 /* regular depth testing */
1871 GLuint m
= _old_depth_test_span( ctx
, n
, x
, y
, z
, mask
);
1876 write_all
= GL_FALSE
;
1880 /* if we get here, something passed the depth test */
1881 ctx
->OcclusionResult
= GL_TRUE
;
1883 /* Texture without alpha test */
1884 if (! ctx
->Color
.AlphaEnabled
) {
1885 ASSERT(ctx
->Texture
._ReallyEnabled
);
1886 _old_swrast_texture_fragments( ctx
, 0, n
, texcoord
, lambda
,
1887 (CONST
GLchan (*)[4]) rgba
, rgba
);
1890 /* Add base and specular colors */
1892 (ctx
->Fog
.ColorSumEnabled
||
1893 (ctx
->Light
.Enabled
&&
1894 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
)))
1895 _old_add_colors( n
, rgba
, spec
); /* rgba = rgba + spec */
1898 if (ctx
->Fog
.Enabled
) {
1899 if (fog
&& !swrast
->_PreferPixelFog
)
1900 _old_fog_rgba_pixels( ctx
, n
, fog
, rgba
);
1902 _old_depth_fog_rgba_pixels( ctx
, n
, z
, rgba
);
1905 /* Antialias coverage application */
1908 for (i
= 0; i
< n
; i
++) {
1909 rgba
[i
][ACOMP
] = (GLchan
) (rgba
[i
][ACOMP
] * coverage
[i
]);
1913 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
1914 multi_write_rgba_span( ctx
, n
, x
, y
, (const GLchan (*)[4]) rgba
, mask
);
1917 /* normal: write to exactly one buffer */
1918 if (ctx
->Color
.ColorLogicOpEnabled
) {
1919 _mesa_logicop_rgba_span( ctx
, n
, x
, y
, rgba
, mask
);
1921 else if (ctx
->Color
.BlendEnabled
) {
1922 _mesa_blend_span( ctx
, n
, x
, y
, rgba
, mask
);
1924 if (colorMask
== 0x0) {
1927 else if (colorMask
!= 0xffffffff) {
1928 _mesa_mask_rgba_span( ctx
, n
, x
, y
, rgba
);
1931 (*swrast
->Driver
.WriteRGBASpan
)( ctx
, n
, x
, y
, (const GLchan (*)[4])rgba
,
1932 write_all
? ((const GLubyte
*) NULL
) : mask
);
1933 if (swrast
->_RasterMask
& ALPHABUF_BIT
) {
1934 _mesa_write_alpha_span( ctx
, n
, x
, y
, (const GLchan (*)[4]) rgba
,
1935 write_all
? ((const GLubyte
*) NULL
) : mask
);
1943 * As above but perform multiple stages of texture application.
1946 _old_write_multitexture_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
1947 const GLdepth z
[], const GLfloat fog
[],
1948 GLfloat texcoord
[MAX_TEXTURE_UNITS
][MAX_WIDTH
][4],
1949 GLfloat lambda
[][MAX_WIDTH
],
1950 GLchan rgbaIn
[MAX_TEXTURE_UNITS
][4],
1951 GLchan spec
[MAX_TEXTURE_UNITS
][4],
1952 const GLfloat coverage
[],
1955 GLubyte mask
[MAX_WIDTH
];
1956 GLboolean write_all
= GL_TRUE
;
1957 GLchan rgbaBackup
[MAX_WIDTH
][4];
1958 GLchan (*rgba
)[4]; /* points to either rgbaIn or rgbaBackup */
1960 const GLubyte
*Null
= 0;
1961 const GLuint texUnits
= ctx
->Const
.MaxTextureUnits
;
1962 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1964 /* init mask to 1's (all pixels are to be written) */
1967 if ((swrast
->_RasterMask
& WINCLIP_BIT
) || primitive
==GL_BITMAP
) {
1968 if ((n
=old_clip_span(ctx
, n
, x
, y
, mask
)) == 0) {
1972 write_all
= GL_FALSE
;
1976 if (primitive
==GL_BITMAP
|| (swrast
->_RasterMask
& MULTI_DRAW_BIT
)
1978 /* must make a copy of the colors since they may be modified */
1979 MEMCPY(rgbaBackup
, rgbaIn
, 4 * n
* sizeof(GLchan
));
1986 /* Do the scissor test */
1987 if (ctx
->Scissor
.Enabled
) {
1988 if ((n
= _old_scissor_span( ctx
, n
, x
, y
, mask
)) == 0) {
1992 write_all
= GL_FALSE
;
1995 /* Polygon Stippling */
1996 if (ctx
->Polygon
.StippleFlag
&& primitive
==GL_POLYGON
) {
1997 old_stipple_polygon_span( ctx
, n
, x
, y
, mask
);
1998 write_all
= GL_FALSE
;
2001 /* Texture with alpha test */
2002 if (ctx
->Color
.AlphaEnabled
) {
2003 /* Texturing without alpha is done after depth-testing which
2004 * gives a potential speed-up.
2006 ASSERT(ctx
->Texture
._ReallyEnabled
);
2007 for (i
= 0; i
< texUnits
; i
++)
2008 _old_swrast_texture_fragments( ctx
, i
, n
, texcoord
[i
], lambda
[i
],
2009 (CONST
GLchan (*)[4]) rgbaIn
, rgba
);
2011 /* Do the alpha test */
2012 if (_mesa_alpha_test( ctx
, n
, (const GLchan (*)[4])rgba
, mask
) == 0) {
2015 write_all
= GL_FALSE
;
2018 if (ctx
->Stencil
.Enabled
) {
2019 /* first stencil test */
2020 if (_old_stencil_and_ztest_span(ctx
, n
, x
, y
, z
, mask
) == GL_FALSE
) {
2023 write_all
= GL_FALSE
;
2025 else if (ctx
->Depth
.Test
) {
2026 /* regular depth testing */
2027 GLuint m
= _old_depth_test_span( ctx
, n
, x
, y
, z
, mask
);
2032 write_all
= GL_FALSE
;
2036 /* if we get here, something passed the depth test */
2037 ctx
->OcclusionResult
= GL_TRUE
;
2039 /* Texture without alpha test */
2040 if (! ctx
->Color
.AlphaEnabled
) {
2041 ASSERT(ctx
->Texture
._ReallyEnabled
);
2042 for (i
= 0; i
< texUnits
; i
++)
2043 _old_swrast_texture_fragments( ctx
, i
, n
, texcoord
[i
], lambda
[i
],
2044 (CONST
GLchan (*)[4]) rgbaIn
, rgba
);
2047 /* Add base and specular colors */
2049 (ctx
->Fog
.ColorSumEnabled
||
2050 (ctx
->Light
.Enabled
&&
2051 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
)))
2052 _old_add_colors( n
, rgba
, spec
); /* rgba = rgba + spec */
2055 if (ctx
->Fog
.Enabled
) {
2056 if (fog
&& !swrast
->_PreferPixelFog
)
2057 _old_fog_rgba_pixels( ctx
, n
, fog
, rgba
);
2059 _old_depth_fog_rgba_pixels( ctx
, n
, z
, rgba
);
2062 /* Antialias coverage application */
2065 for (i
= 0; i
< n
; i
++) {
2066 rgba
[i
][ACOMP
] = (GLchan
) (rgba
[i
][ACOMP
] * coverage
[i
]);
2070 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) {
2071 multi_write_rgba_span( ctx
, n
, x
, y
, (const GLchan (*)[4]) rgba
, mask
);
2074 /* normal: write to exactly one buffer */
2075 const GLuint colorMask
= *((GLuint
*) ctx
->Color
.ColorMask
);
2077 if (ctx
->Color
.ColorLogicOpEnabled
) {
2078 _mesa_logicop_rgba_span( ctx
, n
, x
, y
, rgba
, mask
);
2080 else if (ctx
->Color
.BlendEnabled
) {
2081 _mesa_blend_span( ctx
, n
, x
, y
, rgba
, mask
);
2084 if (colorMask
== 0x0) {
2087 else if (colorMask
!= 0xffffffff) {
2088 _mesa_mask_rgba_span( ctx
, n
, x
, y
, rgba
);
2091 (*swrast
->Driver
.WriteRGBASpan
)( ctx
, n
, x
, y
, (const GLchan (*)[4])rgba
,
2092 write_all
? Null
: mask
);
2093 if (swrast
->_RasterMask
& ALPHABUF_BIT
) {
2094 _mesa_write_alpha_span( ctx
, n
, x
, y
, (const GLchan (*)[4])rgba
,
2095 write_all
? Null
: mask
);
2102 * Read RGBA pixels from frame buffer. Clipping will be done to prevent
2103 * reading ouside the buffer's boundaries.
2106 _mesa_read_rgba_span( GLcontext
*ctx
, GLframebuffer
*buffer
,
2107 GLuint n
, GLint x
, GLint y
, GLchan rgba
[][4] )
2109 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
2110 if (y
< 0 || y
>= buffer
->Height
2111 || x
+ (GLint
) n
< 0 || x
>= buffer
->Width
) {
2112 /* completely above, below, or right */
2113 /* XXX maybe leave undefined? */
2114 BZERO(rgba
, 4 * n
* sizeof(GLchan
));
2119 /* left edge clippping */
2121 length
= (GLint
) n
- skip
;
2123 /* completely left of window */
2126 if (length
> buffer
->Width
) {
2127 length
= buffer
->Width
;
2130 else if ((GLint
) (x
+ n
) > buffer
->Width
) {
2131 /* right edge clipping */
2133 length
= buffer
->Width
- x
;
2135 /* completely to right of window */
2145 (*swrast
->Driver
.ReadRGBASpan
)( ctx
, length
, x
+ skip
, y
, rgba
+ skip
);
2146 if (buffer
->UseSoftwareAlphaBuffers
) {
2147 _mesa_read_alpha_span( ctx
, length
, x
+ skip
, y
, rgba
+ skip
);
2156 * Read CI pixels from frame buffer. Clipping will be done to prevent
2157 * reading ouside the buffer's boundaries.
2160 _mesa_read_index_span( GLcontext
*ctx
, GLframebuffer
*buffer
,
2161 GLuint n
, GLint x
, GLint y
, GLuint indx
[] )
2163 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
2164 if (y
< 0 || y
>= buffer
->Height
2165 || x
+ (GLint
) n
< 0 || x
>= buffer
->Width
) {
2166 /* completely above, below, or right */
2167 BZERO(indx
, n
* sizeof(GLuint
));
2172 /* left edge clippping */
2174 length
= (GLint
) n
- skip
;
2176 /* completely left of window */
2179 if (length
> buffer
->Width
) {
2180 length
= buffer
->Width
;
2183 else if ((GLint
) (x
+ n
) > buffer
->Width
) {
2184 /* right edge clipping */
2186 length
= buffer
->Width
- x
;
2188 /* completely to right of window */
2198 (*swrast
->Driver
.ReadCI32Span
)( ctx
, length
, skip
+ x
, y
, indx
+ skip
);