22aee6c91d25734b78149051f7583cd2ccae6761
3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 #include "s_alphabuf.h"
34 #include "s_context.h"
36 #include "s_masking.h"
37 #include "s_stencil.h"
43 * Clear the color buffer when glColorMask or glIndexMask is in effect.
46 clear_color_buffer_with_masking( GLcontext
*ctx
)
48 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
49 const GLint x
= ctx
->DrawBuffer
->_Xmin
;
50 const GLint y
= ctx
->DrawBuffer
->_Ymin
;
51 const GLint height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
52 const GLint width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
54 if (ctx
->Visual
.rgbMode
) {
58 CLAMPED_FLOAT_TO_CHAN(clearColor
[RCOMP
], ctx
->Color
.ClearColor
[0]);
59 CLAMPED_FLOAT_TO_CHAN(clearColor
[GCOMP
], ctx
->Color
.ClearColor
[1]);
60 CLAMPED_FLOAT_TO_CHAN(clearColor
[BCOMP
], ctx
->Color
.ClearColor
[2]);
61 CLAMPED_FLOAT_TO_CHAN(clearColor
[ACOMP
], ctx
->Color
.ClearColor
[3]);
62 for (i
= 0; i
< height
; i
++) {
63 GLchan rgba
[MAX_WIDTH
][4];
65 for (j
= 0; j
< width
; j
++) {
66 COPY_CHAN4(rgba
[j
], clearColor
);
68 _swrast_mask_rgba_array( ctx
, width
, x
, y
+ i
, rgba
);
69 (*swrast
->Driver
.WriteRGBASpan
)( ctx
, width
, x
, y
+ i
,
70 (CONST
GLchan (*)[4]) rgba
, NULL
);
74 /* Color index mode */
75 GLuint span
[MAX_WIDTH
];
76 GLubyte mask
[MAX_WIDTH
];
78 MEMSET( mask
, 1, width
);
79 for (i
=0;i
<height
;i
++) {
80 for (j
=0;j
<width
;j
++) {
81 span
[j
] = ctx
->Color
.ClearIndex
;
83 _swrast_mask_index_array( ctx
, width
, x
, y
+ i
, span
);
84 (*swrast
->Driver
.WriteCI32Span
)( ctx
, width
, x
, y
+ i
, span
, mask
);
92 * Clear a color buffer without index/channel masking.
95 clear_color_buffer(GLcontext
*ctx
)
97 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
98 const GLint x
= ctx
->DrawBuffer
->_Xmin
;
99 const GLint y
= ctx
->DrawBuffer
->_Ymin
;
100 const GLint height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
101 const GLint width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
103 if (ctx
->Visual
.rgbMode
) {
105 GLchan clearColor
[4];
108 CLAMPED_FLOAT_TO_CHAN(clearColor
[RCOMP
], ctx
->Color
.ClearColor
[0]);
109 CLAMPED_FLOAT_TO_CHAN(clearColor
[GCOMP
], ctx
->Color
.ClearColor
[1]);
110 CLAMPED_FLOAT_TO_CHAN(clearColor
[BCOMP
], ctx
->Color
.ClearColor
[2]);
111 CLAMPED_FLOAT_TO_CHAN(clearColor
[ACOMP
], ctx
->Color
.ClearColor
[3]);
113 ASSERT(*((GLuint
*) &ctx
->Color
.ColorMask
) == 0xffffffff);
114 ASSERT(swrast
->Driver
.WriteRGBASpan
);
116 for (i
= 0; i
< height
; i
++) {
117 (*swrast
->Driver
.WriteMonoRGBASpan
)( ctx
, width
, x
, y
+ i
,
122 /* Color index mode */
124 ASSERT((ctx
->Color
.IndexMask
& ((1 << ctx
->Visual
.indexBits
) - 1))
125 == (GLuint
) ((1 << ctx
->Visual
.indexBits
) - 1));
126 ASSERT(swrast
->Driver
.WriteMonoCISpan
);
127 for (i
= 0; i
< height
; i
++) {
128 (*swrast
->Driver
.WriteMonoCISpan
)( ctx
, width
, x
, y
+ i
,
129 ctx
->Color
.ClearIndex
, NULL
);
137 * Clear the front/back/left/right color buffers.
138 * This function is usually only called if we need to clear the
139 * buffers with masking.
142 clear_color_buffers(GLcontext
*ctx
)
144 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
145 const GLuint colorMask
= *((GLuint
*) &ctx
->Color
.ColorMask
);
148 /* loop over four possible dest color buffers */
149 for (bufferBit
= 1; bufferBit
<= 8; bufferBit
= bufferBit
<< 1) {
150 if (bufferBit
& ctx
->Color
._DrawDestMask
) {
151 (*swrast
->Driver
.SetBuffer
)(ctx
, ctx
->DrawBuffer
, bufferBit
);
153 if (colorMask
!= 0xffffffff) {
154 clear_color_buffer_with_masking(ctx
);
157 clear_color_buffer(ctx
);
162 /* restore default read/draw buffer */
163 _swrast_use_draw_buffer(ctx
);
169 _swrast_Clear( GLcontext
*ctx
, GLbitfield mask
,
171 GLint x
, GLint y
, GLint width
, GLint height
)
173 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
176 GLbitfield legalBits
= DD_FRONT_LEFT_BIT
|
183 assert((mask
& (~legalBits
)) == 0);
187 RENDER_START(swrast
,ctx
);
189 /* do software clearing here */
191 if (mask
& ctx
->Color
._DrawDestMask
) clear_color_buffers(ctx
);
192 if (mask
& GL_DEPTH_BUFFER_BIT
) _swrast_clear_depth_buffer(ctx
);
193 if (mask
& GL_ACCUM_BUFFER_BIT
) _swarst_clear_accum_buffer(ctx
);
194 if (mask
& GL_STENCIL_BUFFER_BIT
) _swrast_clear_stencil_buffer(ctx
);
197 /* clear software-based alpha buffer(s) */
198 if ( (mask
& GL_COLOR_BUFFER_BIT
)
199 && ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
200 && ctx
->Color
.ColorMask
[ACOMP
]) {
201 _swrast_clear_alpha_buffers( ctx
);
204 RENDER_FINISH(swrast
,ctx
);
209 _swrast_alloc_buffers( GLframebuffer
*buffer
)
211 /* Reallocate other buffers if needed. */
212 if (buffer
->UseSoftwareDepthBuffer
) {
213 _swrast_alloc_depth_buffer( buffer
);
215 if (buffer
->UseSoftwareStencilBuffer
) {
216 _swrast_alloc_stencil_buffer( buffer
);
218 if (buffer
->UseSoftwareAccumBuffer
) {
219 _swrast_alloc_accum_buffer( buffer
);
221 if (buffer
->UseSoftwareAlphaBuffers
) {
222 _swrast_alloc_alpha_buffers( buffer
);
228 * Fallback for ctx->Driver.DrawBuffer()
231 _swrast_DrawBuffer( GLcontext
*ctx
, GLenum mode
)
233 _swrast_use_draw_buffer(ctx
);
238 * Setup things so that we read/write spans from the user-designated
239 * read buffer (set via glReadPixels). We usually just have to call
240 * this for glReadPixels, glCopyPixels, etc.
243 _swrast_use_read_buffer( GLcontext
*ctx
)
245 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
247 /* Do this so the software-emulated alpha plane span functions work! */
248 swrast
->CurrentBuffer
= ctx
->Pixel
._ReadSrcMask
;
249 /* Tell the device driver where to read/write spans */
250 (*swrast
->Driver
.SetBuffer
)( ctx
, ctx
->ReadBuffer
, swrast
->CurrentBuffer
);
255 * Setup things so that we read/write spans from the default draw buffer.
256 * This is the usual mode that Mesa's software rasterizer operates in.
259 _swrast_use_draw_buffer( GLcontext
*ctx
)
261 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
263 /* The user can specify rendering to zero, one, two, or four color
264 * buffers simultaneously with glDrawBuffer()!
265 * We don't expect the span/point/line/triangle functions to deal with
266 * that mess so we'll iterate over the multiple buffers as needed.
267 * But usually we only render to one color buffer at a time.
268 * We set ctx->Color._DriverDrawBuffer to that buffer and tell the
269 * device driver to use that buffer.
270 * Look in s_span.c's multi_write_rgba_span() function to see how
271 * we loop over multiple color buffers when needed.
274 if (ctx
->Color
._DrawDestMask
& FRONT_LEFT_BIT
)
275 swrast
->CurrentBuffer
= FRONT_LEFT_BIT
;
276 else if (ctx
->Color
._DrawDestMask
& BACK_LEFT_BIT
)
277 swrast
->CurrentBuffer
= BACK_LEFT_BIT
;
278 else if (ctx
->Color
._DrawDestMask
& FRONT_RIGHT_BIT
)
279 swrast
->CurrentBuffer
= FRONT_RIGHT_BIT
;
280 else if (ctx
->Color
._DrawDestMask
& BACK_RIGHT_BIT
)
281 swrast
->CurrentBuffer
= BACK_RIGHT_BIT
;
283 /* glDrawBuffer(GL_NONE) */
284 swrast
->CurrentBuffer
= FRONT_LEFT_BIT
; /* we always have this buffer */
286 (*swrast
->Driver
.SetBuffer
)( ctx
, ctx
->DrawBuffer
, swrast
->CurrentBuffer
);