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