2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 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.
32 #include "s_alphabuf.h"
33 #include "s_auxbuffer.h"
34 #include "s_context.h"
36 #include "s_masking.h"
37 #include "s_stencil.h"
41 * Clear the color buffer when glColorMask or glIndexMask is in effect.
42 * We'll have specified which color buffer to clear by previously
43 * calling Driver.SetBuffer().
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
);
91 * Clear a color buffer without index/channel masking.
92 * We'll have specified which color buffer to clear by previously
93 * calling Driver.SetBuffer().
96 clear_color_buffer(GLcontext
*ctx
)
98 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
99 const GLint x
= ctx
->DrawBuffer
->_Xmin
;
100 const GLint y
= ctx
->DrawBuffer
->_Ymin
;
101 const GLint height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
102 const GLint width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
104 if (ctx
->Visual
.rgbMode
) {
106 GLchan clearColor
[4];
109 CLAMPED_FLOAT_TO_CHAN(clearColor
[RCOMP
], ctx
->Color
.ClearColor
[0]);
110 CLAMPED_FLOAT_TO_CHAN(clearColor
[GCOMP
], ctx
->Color
.ClearColor
[1]);
111 CLAMPED_FLOAT_TO_CHAN(clearColor
[BCOMP
], ctx
->Color
.ClearColor
[2]);
112 CLAMPED_FLOAT_TO_CHAN(clearColor
[ACOMP
], ctx
->Color
.ClearColor
[3]);
114 ASSERT(*((GLuint
*) &ctx
->Color
.ColorMask
) == 0xffffffff);
115 ASSERT(swrast
->Driver
.WriteRGBASpan
);
117 for (i
= 0; i
< height
; i
++) {
118 (*swrast
->Driver
.WriteMonoRGBASpan
)( ctx
, width
, x
, y
+ i
,
123 /* Color index mode */
125 ASSERT((ctx
->Color
.IndexMask
& ((1 << ctx
->Visual
.indexBits
) - 1))
126 == (GLuint
) ((1 << ctx
->Visual
.indexBits
) - 1));
127 ASSERT(swrast
->Driver
.WriteMonoCISpan
);
128 for (i
= 0; i
< height
; i
++) {
129 (*swrast
->Driver
.WriteMonoCISpan
)( ctx
, width
, x
, y
+ i
,
130 ctx
->Color
.ClearIndex
, NULL
);
137 * Clear the front/back/left/right/aux color buffers.
138 * This function is usually only called if the device driver can't
139 * clear its own color buffers for some reason (such as 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
<= DD_AUX3_BIT
; bufferBit
<<= 1) {
150 if (bufferBit
& ctx
->Color
._DrawDestMask
[0]) {
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
);
168 * Called via the device driver's ctx->Driver.Clear() function if the
169 * device driver can't clear one or more of the buffers itself.
170 * \param mask bitwise-OR of DD_*_BIT flags.
171 * \param all if GL_TRUE, clear whole buffer, else clear specified region.
174 _swrast_Clear( GLcontext
*ctx
, GLbitfield mask
,
176 GLint x
, GLint y
, GLint width
, GLint height
)
178 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
179 (void) all
; (void) x
; (void) y
; (void) width
; (void) height
;
182 const GLbitfield legalBits
=
194 assert((mask
& (~legalBits
)) == 0);
198 RENDER_START(swrast
,ctx
);
200 /* do software clearing here */
202 if (mask
& ctx
->Color
._DrawDestMask
[0]) {
203 clear_color_buffers(ctx
);
204 /* clear software-based alpha buffer(s) */
205 if (ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
206 && ctx
->Color
.ColorMask
[ACOMP
]) {
207 _swrast_clear_alpha_buffers( ctx
);
210 if (mask
& DD_DEPTH_BIT
) {
211 _swrast_clear_depth_buffer(ctx
);
213 if (mask
& DD_ACCUM_BIT
) {
214 _swrast_clear_accum_buffer(ctx
);
216 if (mask
& DD_STENCIL_BIT
) {
217 _swrast_clear_stencil_buffer(ctx
);
221 RENDER_FINISH(swrast
,ctx
);
226 * Typically called via ctx->Driver.ResizeBuffers().
227 * Reallocate all software-based depth/stencil/accum/etc buffers
228 * to match current window dimensions.
231 _swrast_alloc_buffers( GLframebuffer
*buffer
)
233 /* Reallocate other buffers if needed. */
234 if (buffer
->UseSoftwareDepthBuffer
) {
235 _swrast_alloc_depth_buffer( buffer
);
237 if (buffer
->UseSoftwareStencilBuffer
) {
238 _swrast_alloc_stencil_buffer( buffer
);
240 if (buffer
->UseSoftwareAccumBuffer
) {
241 _swrast_alloc_accum_buffer( buffer
);
243 if (buffer
->UseSoftwareAlphaBuffers
) {
244 _swrast_alloc_alpha_buffers( buffer
);
246 if (buffer
->UseSoftwareAuxBuffers
) {
247 _swrast_alloc_aux_buffers( buffer
);
253 * Fallback for ctx->Driver.DrawBuffer()
256 _swrast_DrawBuffer( GLcontext
*ctx
, GLenum mode
)
259 _swrast_use_draw_buffer(ctx
);
264 * Fallback for ctx->Driver.DrawBuffers()
267 _swrast_DrawBuffers( GLcontext
*ctx
, GLsizei n
, const GLenum
*buffers
)
269 _swrast_use_draw_buffer(ctx
);
274 * Setup things so that we read/write spans from the user-designated
275 * read buffer (set via glReadPixels). We usually just have to call
276 * this for glReadPixels, glCopyPixels, etc.
279 _swrast_use_read_buffer( GLcontext
*ctx
)
281 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
283 /* Do this so the software-emulated alpha plane span functions work! */
284 swrast
->CurrentBufferBit
= ctx
->Pixel
._ReadSrcMask
;
285 /* Tell the device driver where to read/write spans */
286 swrast
->Driver
.SetBuffer(ctx
, ctx
->ReadBuffer
, swrast
->CurrentBufferBit
);
291 * Setup things so that we read/write spans from the default draw buffer.
292 * This is the usual mode that Mesa's software rasterizer operates in.
295 _swrast_use_draw_buffer( GLcontext
*ctx
)
297 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
299 /* The user can specify rendering to zero, one, two, or four color
300 * buffers simultaneously with glDrawBuffer()!
301 * We don't expect the span/point/line/triangle functions to deal with
302 * that mess so we'll iterate over the multiple buffers as needed.
303 * But usually we only render to one color buffer at a time.
304 * We set ctx->Color._DriverDrawBuffer to that buffer and tell the
305 * device driver to use that buffer.
306 * Look in s_span.c's multi_write_rgba_span() function to see how
307 * we loop over multiple color buffers when needed.
310 if (ctx
->Color
._DrawDestMask
[0] & DD_FRONT_LEFT_BIT
)
311 swrast
->CurrentBufferBit
= DD_FRONT_LEFT_BIT
;
312 else if (ctx
->Color
._DrawDestMask
[0] & DD_BACK_LEFT_BIT
)
313 swrast
->CurrentBufferBit
= DD_BACK_LEFT_BIT
;
314 else if (ctx
->Color
._DrawDestMask
[0] & DD_FRONT_RIGHT_BIT
)
315 swrast
->CurrentBufferBit
= DD_FRONT_RIGHT_BIT
;
316 else if (ctx
->Color
._DrawDestMask
[0] & DD_BACK_RIGHT_BIT
)
317 swrast
->CurrentBufferBit
= DD_BACK_RIGHT_BIT
;
318 else if (ctx
->Color
._DrawDestMask
[0] & DD_AUX0_BIT
)
319 swrast
->CurrentBufferBit
= DD_AUX0_BIT
;
320 else if (ctx
->Color
._DrawDestMask
[0] & DD_AUX1_BIT
)
321 swrast
->CurrentBufferBit
= DD_AUX1_BIT
;
322 else if (ctx
->Color
._DrawDestMask
[0] & DD_AUX2_BIT
)
323 swrast
->CurrentBufferBit
= DD_AUX2_BIT
;
324 else if (ctx
->Color
._DrawDestMask
[0] & DD_AUX3_BIT
)
325 swrast
->CurrentBufferBit
= DD_AUX3_BIT
;
327 /* glDrawBuffer(GL_NONE) */
328 swrast
->CurrentBufferBit
= DD_FRONT_LEFT_BIT
; /* we always have this buffer */
330 swrast
->Driver
.SetBuffer(ctx
, ctx
->DrawBuffer
, swrast
->CurrentBufferBit
);