~ubuntu-branches/ubuntu/jaunty/mesa/jaunty

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/intel/intel_clear.c

  • Committer: Bazaar Package Importer
  • Author(s): Timo Aaltonen
  • Date: 2009-04-03 12:42:06 UTC
  • mfrom: (1.2.16 upstream) (3.1.5 experimental)
  • Revision ID: james.westby@ubuntu.com-20090403124206-0oo9dl0tcmd0qr38
Tags: 7.4-0ubuntu1
* New upstream release, merge from debian-experimental
  (LP: #330476, #347171, #349127)
* Drop 103_rs600_support.patch, included in this version.
* Drop 104_swrast_fbconfigs.patch, included in this version.
* Add 103_bump_965_texture_limit.diff. (LP: #146298)
* Add 104_fix_dri2_ext_tfp.diff. (LP: #324854)

Show diffs side-by-side

added added

removed removed

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