GL_INTENSITY case was incorrect in extract_float_rgba()
[mesa.git] / src / mesa / swrast / s_buffers.c
1 /* $Id: s_buffers.c,v 1.8 2001/03/19 02:25:36 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 */
26
27
28 #include "glheader.h"
29 #include "macros.h"
30 #include "mem.h"
31
32 #include "s_accum.h"
33 #include "s_alphabuf.h"
34 #include "s_context.h"
35 #include "s_depth.h"
36 #include "s_masking.h"
37 #include "s_stencil.h"
38
39
40
41
42 /*
43 * Clear the color buffer when glColorMask or glIndexMask is in effect.
44 */
45 static void
46 clear_color_buffer_with_masking( GLcontext *ctx )
47 {
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;
53
54 if (ctx->Visual.rgbMode) {
55 /* RGBA mode */
56 const GLchan r = ctx->Color.ClearColor[0];
57 const GLchan g = ctx->Color.ClearColor[1];
58 const GLchan b = ctx->Color.ClearColor[2];
59 const GLchan a = ctx->Color.ClearColor[3];
60 GLint i;
61 for (i = 0; i < height; i++) {
62 GLchan rgba[MAX_WIDTH][4];
63 GLint j;
64 for (j = 0; j < width; j++) {
65 rgba[j][RCOMP] = r;
66 rgba[j][GCOMP] = g;
67 rgba[j][BCOMP] = b;
68 rgba[j][ACOMP] = a;
69 }
70 _mesa_mask_rgba_span( ctx, width, x, y + i, rgba );
71 (*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i,
72 (CONST GLchan (*)[4]) rgba, NULL );
73 }
74 }
75 else {
76 /* Color index mode */
77 GLuint span[MAX_WIDTH];
78 GLubyte mask[MAX_WIDTH];
79 GLint i, j;
80 MEMSET( mask, 1, width );
81 for (i=0;i<height;i++) {
82 for (j=0;j<width;j++) {
83 span[j] = ctx->Color.ClearIndex;
84 }
85 _mesa_mask_index_span( ctx, width, x, y + i, span );
86 (*swrast->Driver.WriteCI32Span)( ctx, width, x, y + i, span, mask );
87 }
88 }
89 }
90
91
92
93 /*
94 * Clear a color buffer without index/channel masking.
95 */
96 static void
97 clear_color_buffer(GLcontext *ctx)
98 {
99 SWcontext *swrast = SWRAST_CONTEXT(ctx);
100 const GLint x = ctx->DrawBuffer->_Xmin;
101 const GLint y = ctx->DrawBuffer->_Ymin;
102 const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
103 const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
104
105 if (ctx->Visual.rgbMode) {
106 /* RGBA mode */
107 const GLchan r = ctx->Color.ClearColor[0];
108 const GLchan g = ctx->Color.ClearColor[1];
109 const GLchan b = ctx->Color.ClearColor[2];
110 const GLchan a = ctx->Color.ClearColor[3];
111 GLchan span[MAX_WIDTH][4];
112 GLint i;
113
114 ASSERT(*((GLuint *) &ctx->Color.ColorMask) == 0xffffffff);
115
116 for (i = 0; i < width; i++) {
117 span[i][RCOMP] = r;
118 span[i][GCOMP] = g;
119 span[i][BCOMP] = b;
120 span[i][ACOMP] = a;
121 }
122 for (i = 0; i < height; i++) {
123 (*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i,
124 (CONST GLchan (*)[4]) span, NULL );
125 }
126 }
127 else {
128 /* Color index mode */
129 ASSERT((ctx->Color.IndexMask & ((1 << ctx->Visual.indexBits) - 1))
130 == (GLuint) ((1 << ctx->Visual.indexBits) - 1));
131 if (ctx->Visual.indexBits == 8) {
132 /* 8-bit clear */
133 GLubyte span[MAX_WIDTH];
134 GLint i;
135 MEMSET(span, ctx->Color.ClearIndex, width);
136 for (i = 0; i < height; i++) {
137 (*swrast->Driver.WriteCI8Span)( ctx, width, x, y + i, span, NULL );
138 }
139 }
140 else {
141 /* non 8-bit clear */
142 GLuint span[MAX_WIDTH];
143 GLint i;
144 for (i = 0; i < width; i++) {
145 span[i] = ctx->Color.ClearIndex;
146 }
147 for (i = 0; i < height; i++) {
148 (*swrast->Driver.WriteCI32Span)( ctx, width, x, y + i, span, NULL );
149 }
150 }
151 }
152 }
153
154
155
156 /*
157 * Clear the front/back/left/right color buffers.
158 * This function is usually only called if we need to clear the
159 * buffers with masking.
160 */
161 static void
162 clear_color_buffers(GLcontext *ctx)
163 {
164 SWcontext *swrast = SWRAST_CONTEXT(ctx);
165 const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
166 GLuint bufferBit;
167
168 /* loop over four possible dest color buffers */
169 for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
170 if (bufferBit & ctx->Color.DrawDestMask) {
171 if (bufferBit == FRONT_LEFT_BIT) {
172 (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
173 (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_FRONT_LEFT);
174 }
175 else if (bufferBit == FRONT_RIGHT_BIT) {
176 (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT);
177 (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_FRONT_RIGHT);
178 }
179 else if (bufferBit == BACK_LEFT_BIT) {
180 (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT);
181 (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_BACK_LEFT);
182 }
183 else {
184 (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
185 (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_BACK_RIGHT);
186 }
187
188 if (colorMask != 0xffffffff) {
189 clear_color_buffer_with_masking(ctx);
190 }
191 else {
192 clear_color_buffer(ctx);
193 }
194 }
195 }
196
197 /* restore default read/draw buffers */
198 (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer );
199 (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer );
200 }
201
202
203
204 void
205 _swrast_Clear( GLcontext *ctx, GLbitfield mask,
206 GLboolean all,
207 GLint x, GLint y, GLint width, GLint height )
208 {
209 SWcontext *swrast = SWRAST_CONTEXT(ctx);
210 #ifdef DEBUG
211 {
212 GLbitfield legalBits = DD_FRONT_LEFT_BIT |
213 DD_FRONT_RIGHT_BIT |
214 DD_BACK_LEFT_BIT |
215 DD_BACK_RIGHT_BIT |
216 DD_DEPTH_BIT |
217 DD_STENCIL_BIT |
218 DD_ACCUM_BIT;
219 assert((mask & (~legalBits)) == 0);
220 }
221 #endif
222
223 RENDER_START(swrast,ctx);
224
225 /* do software clearing here */
226 if (mask) {
227 if (mask & ctx->Color.DrawDestMask) clear_color_buffers(ctx);
228 if (mask & GL_DEPTH_BUFFER_BIT) _mesa_clear_depth_buffer(ctx);
229 if (mask & GL_ACCUM_BUFFER_BIT) _mesa_clear_accum_buffer(ctx);
230 if (mask & GL_STENCIL_BUFFER_BIT) _mesa_clear_stencil_buffer(ctx);
231 }
232
233 /* clear software-based alpha buffer(s) */
234 if ( (mask & GL_COLOR_BUFFER_BIT)
235 && ctx->DrawBuffer->UseSoftwareAlphaBuffers
236 && ctx->Color.ColorMask[ACOMP]) {
237 _mesa_clear_alpha_buffers( ctx );
238 }
239
240 RENDER_FINISH(swrast,ctx);
241 }
242
243
244 void
245 _swrast_alloc_buffers( GLcontext *ctx )
246 {
247 /* Reallocate other buffers if needed. */
248 if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
249 _mesa_alloc_depth_buffer( ctx );
250 }
251 if (ctx->DrawBuffer->UseSoftwareStencilBuffer) {
252 _mesa_alloc_stencil_buffer( ctx );
253 }
254 if (ctx->DrawBuffer->UseSoftwareAccumBuffer) {
255 _mesa_alloc_accum_buffer( ctx );
256 }
257 if (ctx->DrawBuffer->UseSoftwareAlphaBuffers) {
258 _mesa_alloc_alpha_buffers( ctx );
259 }
260 }