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