aed95c7c56157776a3bb04e27614d29565b34d68
[mesa.git] / src / mesa / drivers / dri / intel / intel_clear.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * Copyright 2009 Intel Corporation.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * 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
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29 #include "main/glheader.h"
30 #include "main/enums.h"
31 #include "main/image.h"
32 #include "main/mtypes.h"
33 #include "main/attrib.h"
34 #include "main/blend.h"
35 #include "main/bufferobj.h"
36 #include "main/buffers.h"
37 #include "main/depth.h"
38 #include "main/enable.h"
39 #include "main/macros.h"
40 #include "main/matrix.h"
41 #include "main/polygon.h"
42 #include "main/texstate.h"
43 #include "main/shaders.h"
44 #include "main/stencil.h"
45 #include "main/varray.h"
46 #include "glapi/dispatch.h"
47 #include "swrast/swrast.h"
48
49 #include "intel_context.h"
50 #include "intel_blit.h"
51 #include "intel_chipset.h"
52 #include "intel_clear.h"
53 #include "intel_fbo.h"
54 #include "intel_pixel.h"
55
56 #define FILE_DEBUG_FLAG DEBUG_BLIT
57
58 #define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \
59 BUFFER_BIT_FRONT_LEFT | \
60 BUFFER_BIT_COLOR0 | \
61 BUFFER_BIT_COLOR1 | \
62 BUFFER_BIT_COLOR2 | \
63 BUFFER_BIT_COLOR3 | \
64 BUFFER_BIT_COLOR4 | \
65 BUFFER_BIT_COLOR5 | \
66 BUFFER_BIT_COLOR6 | \
67 BUFFER_BIT_COLOR7)
68
69 /**
70 * Perform glClear where mask contains only color, depth, and/or stencil.
71 *
72 * The implementation is based on calling into Mesa to set GL state and
73 * performing normal triangle rendering. The intent of this path is to
74 * have as generic a path as possible, so that any driver could make use of
75 * it.
76 */
77 void
78 intel_clear_tris(GLcontext *ctx, GLbitfield mask)
79 {
80 struct intel_context *intel = intel_context(ctx);
81 GLfloat vertices[4][3];
82 GLfloat color[4][4];
83 GLfloat dst_z;
84 struct gl_framebuffer *fb = ctx->DrawBuffer;
85 int i;
86 GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
87 GLuint saved_shader_program = 0;
88 unsigned int saved_active_texture;
89
90 assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH |
91 BUFFER_BIT_STENCIL)) == 0);
92
93 _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
94 GL_CURRENT_BIT |
95 GL_DEPTH_BUFFER_BIT |
96 GL_ENABLE_BIT |
97 GL_POLYGON_BIT |
98 GL_STENCIL_BUFFER_BIT |
99 GL_TRANSFORM_BIT |
100 GL_CURRENT_BIT);
101 _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
102 saved_active_texture = ctx->Texture.CurrentUnit;
103
104 /* Disable existing GL state we don't want to apply to a clear. */
105 _mesa_Disable(GL_ALPHA_TEST);
106 _mesa_Disable(GL_BLEND);
107 _mesa_Disable(GL_CULL_FACE);
108 _mesa_Disable(GL_FOG);
109 _mesa_Disable(GL_POLYGON_SMOOTH);
110 _mesa_Disable(GL_POLYGON_STIPPLE);
111 _mesa_Disable(GL_POLYGON_OFFSET_FILL);
112 _mesa_Disable(GL_LIGHTING);
113 _mesa_Disable(GL_CLIP_PLANE0);
114 _mesa_Disable(GL_CLIP_PLANE1);
115 _mesa_Disable(GL_CLIP_PLANE2);
116 _mesa_Disable(GL_CLIP_PLANE3);
117 _mesa_Disable(GL_CLIP_PLANE4);
118 _mesa_Disable(GL_CLIP_PLANE5);
119 _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
120 if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
121 saved_fp_enable = GL_TRUE;
122 _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
123 }
124 if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
125 saved_vp_enable = GL_TRUE;
126 _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
127 }
128 if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) {
129 saved_shader_program = ctx->Shader.CurrentProgram->Name;
130 _mesa_UseProgramObjectARB(0);
131 }
132
133 if (ctx->Texture._EnabledUnits != 0) {
134 int i;
135
136 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
137 _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
138 _mesa_Disable(GL_TEXTURE_1D);
139 _mesa_Disable(GL_TEXTURE_2D);
140 _mesa_Disable(GL_TEXTURE_3D);
141 if (ctx->Extensions.ARB_texture_cube_map)
142 _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
143 if (ctx->Extensions.NV_texture_rectangle)
144 _mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
145 if (ctx->Extensions.MESA_texture_array) {
146 _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
147 _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
148 }
149 }
150 }
151
152 #if FEATURE_ARB_vertex_buffer_object
153 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
154 _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
155 #endif
156
157 intel_meta_set_passthrough_transform(intel);
158
159 for (i = 0; i < 4; i++) {
160 color[i][0] = ctx->Color.ClearColor[0];
161 color[i][1] = ctx->Color.ClearColor[1];
162 color[i][2] = ctx->Color.ClearColor[2];
163 color[i][3] = ctx->Color.ClearColor[3];
164 }
165
166 /* convert clear Z from [0,1] to NDC coord in [-1,1] */
167 dst_z = -1.0 + 2.0 * ctx->Depth.Clear;
168
169 /* Prepare the vertices, which are the same regardless of which buffer we're
170 * drawing to.
171 */
172 vertices[0][0] = fb->_Xmin;
173 vertices[0][1] = fb->_Ymin;
174 vertices[0][2] = dst_z;
175 vertices[1][0] = fb->_Xmax;
176 vertices[1][1] = fb->_Ymin;
177 vertices[1][2] = dst_z;
178 vertices[2][0] = fb->_Xmax;
179 vertices[2][1] = fb->_Ymax;
180 vertices[2][2] = dst_z;
181 vertices[3][0] = fb->_Xmin;
182 vertices[3][1] = fb->_Ymax;
183 vertices[3][2] = dst_z;
184
185 _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color);
186 _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices);
187 _mesa_Enable(GL_COLOR_ARRAY);
188 _mesa_Enable(GL_VERTEX_ARRAY);
189
190 while (mask != 0) {
191 GLuint this_mask = 0;
192 GLuint color_bit;
193
194 color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
195 if (color_bit != 0)
196 this_mask |= (1 << (color_bit - 1));
197
198 /* Clear depth/stencil in the same pass as color. */
199 this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
200
201 /* Select the current color buffer and use the color write mask if
202 * we have one, otherwise don't write any color channels.
203 */
204 if (this_mask & BUFFER_BIT_FRONT_LEFT)
205 _mesa_DrawBuffer(GL_FRONT_LEFT);
206 else if (this_mask & BUFFER_BIT_BACK_LEFT)
207 _mesa_DrawBuffer(GL_BACK_LEFT);
208 else if (color_bit != 0)
209 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 +
210 (color_bit - BUFFER_COLOR0 - 1));
211 else
212 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
213
214 /* Control writing of the depth clear value to depth. */
215 if (this_mask & BUFFER_BIT_DEPTH) {
216 _mesa_DepthFunc(GL_ALWAYS);
217 _mesa_Enable(GL_DEPTH_TEST);
218 } else {
219 _mesa_Disable(GL_DEPTH_TEST);
220 _mesa_DepthMask(GL_FALSE);
221 }
222
223 /* Control writing of the stencil clear value to stencil. */
224 if (this_mask & BUFFER_BIT_STENCIL) {
225 _mesa_Enable(GL_STENCIL_TEST);
226 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
227 _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear,
228 ctx->Stencil.WriteMask[0]);
229 } else {
230 _mesa_Disable(GL_STENCIL_TEST);
231 }
232
233 CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
234
235 mask &= ~this_mask;
236 }
237
238 intel_meta_restore_transform(intel);
239
240 _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
241 if (saved_fp_enable)
242 _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
243 if (saved_vp_enable)
244 _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
245
246 if (saved_shader_program)
247 _mesa_UseProgramObjectARB(saved_shader_program);
248
249 _mesa_PopClientAttrib();
250 _mesa_PopAttrib();
251 }
252
253 static const char *buffer_names[] = {
254 [BUFFER_FRONT_LEFT] = "front",
255 [BUFFER_BACK_LEFT] = "back",
256 [BUFFER_FRONT_RIGHT] = "front right",
257 [BUFFER_BACK_RIGHT] = "back right",
258 [BUFFER_DEPTH] = "depth",
259 [BUFFER_STENCIL] = "stencil",
260 [BUFFER_ACCUM] = "accum",
261 [BUFFER_AUX0] = "aux0",
262 [BUFFER_COLOR0] = "color0",
263 [BUFFER_COLOR1] = "color1",
264 [BUFFER_COLOR2] = "color2",
265 [BUFFER_COLOR3] = "color3",
266 [BUFFER_COLOR4] = "color4",
267 [BUFFER_COLOR5] = "color5",
268 [BUFFER_COLOR6] = "color6",
269 [BUFFER_COLOR7] = "color7",
270 };
271
272 /**
273 * Called by ctx->Driver.Clear.
274 */
275 static void
276 intelClear(GLcontext *ctx, GLbitfield mask)
277 {
278 struct intel_context *intel = intel_context(ctx);
279 const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
280 GLbitfield tri_mask = 0;
281 GLbitfield blit_mask = 0;
282 GLbitfield swrast_mask = 0;
283 struct gl_framebuffer *fb = ctx->DrawBuffer;
284 GLuint i;
285
286 if (0)
287 fprintf(stderr, "%s\n", __FUNCTION__);
288
289 /* HW color buffers (front, back, aux, generic FBO, etc) */
290 if (colorMask == ~0) {
291 /* clear all R,G,B,A */
292 /* XXX FBO: need to check if colorbuffers are software RBOs! */
293 blit_mask |= (mask & BUFFER_BITS_COLOR);
294 }
295 else {
296 /* glColorMask in effect */
297 tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
298 }
299
300 /* HW stencil */
301 if (mask & BUFFER_BIT_STENCIL) {
302 const struct intel_region *stencilRegion
303 = intel_get_rb_region(fb, BUFFER_STENCIL);
304 if (stencilRegion) {
305 /* have hw stencil */
306 if (IS_965(intel->intelScreen->deviceID) ||
307 (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
308 /* We have to use the 3D engine if we're clearing a partial mask
309 * of the stencil buffer, or if we're on a 965 which has a tiled
310 * depth/stencil buffer in a layout we can't blit to.
311 */
312 tri_mask |= BUFFER_BIT_STENCIL;
313 }
314 else {
315 /* clearing all stencil bits, use blitting */
316 blit_mask |= BUFFER_BIT_STENCIL;
317 }
318 }
319 }
320
321 /* HW depth */
322 if (mask & BUFFER_BIT_DEPTH) {
323 /* clear depth with whatever method is used for stencil (see above) */
324 if (IS_965(intel->intelScreen->deviceID) ||
325 tri_mask & BUFFER_BIT_STENCIL)
326 tri_mask |= BUFFER_BIT_DEPTH;
327 else
328 blit_mask |= BUFFER_BIT_DEPTH;
329 }
330
331 /* If we're doing a tri pass for depth/stencil, include a likely color
332 * buffer with it.
333 */
334 if (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
335 int color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
336 if (color_bit != 0) {
337 tri_mask |= blit_mask & (1 << (color_bit - 1));
338 blit_mask &= ~(1 << (color_bit - 1));
339 }
340 }
341
342 /* SW fallback clearing */
343 swrast_mask = mask & ~tri_mask & ~blit_mask;
344
345 for (i = 0; i < BUFFER_COUNT; i++) {
346 GLuint bufBit = 1 << i;
347 if ((blit_mask | tri_mask) & bufBit) {
348 if (!fb->Attachment[i].Renderbuffer->ClassID) {
349 blit_mask &= ~bufBit;
350 tri_mask &= ~bufBit;
351 swrast_mask |= bufBit;
352 }
353 }
354 }
355
356 if (blit_mask) {
357 if (INTEL_DEBUG & DEBUG_BLIT) {
358 DBG("blit clear:");
359 for (i = 0; i < BUFFER_COUNT; i++) {
360 if (blit_mask & (1 << i))
361 DBG(" %s", buffer_names[i]);
362 }
363 DBG("\n");
364 }
365 intelClearWithBlit(ctx, blit_mask);
366 }
367
368 if (tri_mask) {
369 if (INTEL_DEBUG & DEBUG_BLIT) {
370 DBG("tri clear:");
371 for (i = 0; i < BUFFER_COUNT; i++) {
372 if (tri_mask & (1 << i))
373 DBG(" %s", buffer_names[i]);
374 }
375 DBG("\n");
376 }
377 intel_clear_tris(ctx, tri_mask);
378 }
379
380 if (swrast_mask) {
381 if (INTEL_DEBUG & DEBUG_BLIT) {
382 DBG("swrast clear:");
383 for (i = 0; i < BUFFER_COUNT; i++) {
384 if (swrast_mask & (1 << i))
385 DBG(" %s", buffer_names[i]);
386 }
387 DBG("\n");
388 }
389 _swrast_Clear(ctx, swrast_mask);
390 }
391 }
392
393
394 void
395 intelInitClearFuncs(struct dd_function_table *functions)
396 {
397 functions->Clear = intelClear;
398 }