brw_clear.c revision c96bac0950eda6e707455b0c1ee29c1d87daf727
1090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com/**************************************************************************
2090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com *
3090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * Copyright 2009 Intel Corporation.
5090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * All Rights Reserved.
6090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com *
7090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * Permission is hereby granted, free of charge, to any person obtaining a
8090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * copy of this software and associated documentation files (the
9090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * "Software"), to deal in the Software without restriction, including
10090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * without limitation the rights to use, copy, modify, merge, publish,
11090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * distribute, sub license, and/or sell copies of the Software, and to
12090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * permit persons to whom the Software is furnished to do so, subject to
13090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * the following conditions:
14090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com *
15090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * The above copyright notice and this permission notice (including the
16090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * next paragraph) shall be included in all copies or substantial portions
17090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * of the Software.
18090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com *
19090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com *
27090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com **************************************************************************/
28090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
29090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/glheader.h"
30090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/enums.h"
31090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/image.h"
32090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/mtypes.h"
33090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/attrib.h"
34090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/blend.h"
35090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/bufferobj.h"
36090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/buffers.h"
37090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/depth.h"
38090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/enable.h"
39246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com#include "main/macros.h"
40090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/matrix.h"
41090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/texstate.h"
42090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "main/stencil.h"
43246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com#include "main/varray.h"
44090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "glapi/dispatch.h"
45090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "swrast/swrast.h"
46090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
47246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com#include "intel_context.h"
48090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "intel_blit.h"
49090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "intel_chipset.h"
50246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com#include "intel_clear.h"
51246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com#include "intel_fbo.h"
52090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#include "intel_pixel.h"
53246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
54090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com#define FILE_DEBUG_FLAG DEBUG_BLIT
55090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
56090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com/**
57246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com * Perform glClear where mask contains only color, depth, and/or stencil.
58090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com *
59090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * The implementation is based on calling into Mesa to set GL state and
60090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * performing normal triangle rendering.  The intent of this path is to
61246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com * have as generic a path as possible, so that any driver could make use of
62090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com * it.
63090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com */
64090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.comvoid
65090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.comintel_clear_tris(GLcontext *ctx, GLbitfield mask)
66246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com{
67090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   struct intel_context *intel = intel_context(ctx);
68090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   GLfloat vertices[4][4];
69246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   GLfloat color[4][4];
70090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   GLfloat dst_z;
71090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   struct gl_framebuffer *fb = ctx->DrawBuffer;
72090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   int i;
73246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
74090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   unsigned int saved_active_texture;
75246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
76246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   assert((mask & ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT |
77090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com		    BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) == 0);
78090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
79090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
80246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com		    GL_CURRENT_BIT |
81246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com		    GL_DEPTH_BUFFER_BIT |
82090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com		    GL_ENABLE_BIT |
83090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com		    GL_STENCIL_BUFFER_BIT |
84090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com		    GL_TRANSFORM_BIT |
85090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com		    GL_CURRENT_BIT);
86090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
87090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   saved_active_texture = ctx->Texture.CurrentUnit;
88090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
89090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   /* Disable existing GL state we don't want to apply to a clear. */
90090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_Disable(GL_ALPHA_TEST);
91246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   _mesa_Disable(GL_BLEND);
92246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   _mesa_Disable(GL_CULL_FACE);
93090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_Disable(GL_FOG);
94246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   _mesa_Disable(GL_POLYGON_SMOOTH);
95090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_Disable(GL_POLYGON_STIPPLE);
96090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_Disable(GL_POLYGON_OFFSET_FILL);
97090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_Disable(GL_LIGHTING);
98246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   _mesa_Disable(GL_CLIP_PLANE0);
99090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_Disable(GL_CLIP_PLANE1);
100090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_Disable(GL_CLIP_PLANE2);
101090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_Disable(GL_CLIP_PLANE3);
102246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   _mesa_Disable(GL_CLIP_PLANE4);
103090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_Disable(GL_CLIP_PLANE5);
104090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
105090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      saved_fp_enable = GL_TRUE;
106246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
107246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   }
108090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
109090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      saved_vp_enable = GL_TRUE;
110090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
111246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   }
112246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
113090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   if (ctx->Texture._EnabledUnits != 0) {
114090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      int i;
115246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
116090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
117090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
118090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_Disable(GL_TEXTURE_1D);
119246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com	 _mesa_Disable(GL_TEXTURE_2D);
120090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_Disable(GL_TEXTURE_3D);
121246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com	 if (ctx->Extensions.ARB_texture_cube_map)
122246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com	    _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
123090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 if (ctx->Extensions.NV_texture_rectangle)
124090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	    _mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
125090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 if (ctx->Extensions.MESA_texture_array) {
126246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com	    _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
127246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com	    _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
128090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 }
129090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      }
130090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   }
131090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
132090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   intel_meta_set_passthrough_transform(intel);
133246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
134246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   for (i = 0; i < 4; i++) {
135090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      color[i][0] = ctx->Color.ClearColor[0];
136090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      color[i][1] = ctx->Color.ClearColor[1];
137090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      color[i][2] = ctx->Color.ClearColor[2];
138090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      color[i][3] = ctx->Color.ClearColor[3];
139246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   }
140246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
141090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   /* convert clear Z from [0,1] to NDC coord in [-1,1] */
142246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   dst_z = -1.0 + 2.0 * ctx->Depth.Clear;
143090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
144090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   /* Prepare the vertices, which are the same regardless of which buffer we're
145090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com    * drawing to.
146246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    */
147090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   vertices[0][0] = fb->_Xmin;
148246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   vertices[0][1] = fb->_Ymin;
149090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   vertices[0][2] = dst_z;
150090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   vertices[0][3] = 1.0;
151090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   vertices[1][0] = fb->_Xmax;
152246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   vertices[1][1] = fb->_Ymin;
153090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   vertices[1][2] = dst_z;
154090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   vertices[1][3] = 1.0;
155090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   vertices[2][0] = fb->_Xmax;
156090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   vertices[2][1] = fb->_Ymax;
157090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   vertices[2][2] = dst_z;
158246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   vertices[2][3] = 1.0;
159090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   vertices[3][0] = fb->_Xmin;
160090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   vertices[3][1] = fb->_Ymax;
161090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   vertices[3][2] = dst_z;
162246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   vertices[3][3] = 1.0;
163090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
164246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color);
165246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices);
166090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_Enable(GL_COLOR_ARRAY);
167090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_Enable(GL_VERTEX_ARRAY);
168090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
169246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   while (mask != 0) {
170246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      GLuint this_mask = 0;
171090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
172090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      if (mask & BUFFER_BIT_BACK_LEFT)
173090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 this_mask = BUFFER_BIT_BACK_LEFT;
174090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      else if (mask & BUFFER_BIT_FRONT_LEFT)
175090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 this_mask = BUFFER_BIT_FRONT_LEFT;
176090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
177090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      /* Clear depth/stencil in the same pass as color. */
178090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
179090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
180090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      /* Select the current color buffer and use the color write mask if
181090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com       * we have one, otherwise don't write any color channels.
182246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com       */
183246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      if (this_mask & BUFFER_BIT_FRONT_LEFT)
184090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_DrawBuffer(GL_FRONT_LEFT);
185246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      else if (this_mask & BUFFER_BIT_BACK_LEFT)
186090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_DrawBuffer(GL_BACK_LEFT);
187090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      else
188090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
189246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
190090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      /* Control writing of the depth clear value to depth. */
191090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      if (this_mask & BUFFER_BIT_DEPTH) {
192090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_DepthFunc(GL_ALWAYS);
193090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_Enable(GL_DEPTH_TEST);
194090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      } else {
195090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_Disable(GL_DEPTH_TEST);
196090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_DepthMask(GL_FALSE);
197246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      }
198090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
199090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      /* Control writing of the stencil clear value to stencil. */
200090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      if (this_mask & BUFFER_BIT_STENCIL) {
201090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_Enable(GL_STENCIL_TEST);
202246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com	 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
203090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear,
204090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com				   ctx->Stencil.WriteMask[0]);
205246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      } else {
206090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com	 _mesa_Disable(GL_STENCIL_TEST);
207090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      }
208090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
209246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
210090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
211246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com      mask &= ~this_mask;
212246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   }
213090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
214090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   intel_meta_restore_transform(intel);
215090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
216090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
217246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   if (saved_fp_enable)
218090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
219090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   if (saved_vp_enable)
220090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com      _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
221246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
222090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   _mesa_PopClientAttrib();
223246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com   _mesa_PopAttrib();
224246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com}
225090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com
226090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.comstatic const char *buffer_names[] = {
227090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   [BUFFER_FRONT_LEFT] = "front",
228090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   [BUFFER_BACK_LEFT] = "back",
229090ea9e59646e627865c40f9758cfed067a575a1arthurhsu@google.com   [BUFFER_FRONT_RIGHT] = "front right",
230   [BUFFER_BACK_RIGHT] = "back right",
231   [BUFFER_AUX0] = "aux0",
232   [BUFFER_AUX1] = "aux1",
233   [BUFFER_AUX2] = "aux2",
234   [BUFFER_AUX3] = "aux3",
235   [BUFFER_DEPTH] = "depth",
236   [BUFFER_STENCIL] = "stencil",
237   [BUFFER_ACCUM] = "accum",
238   [BUFFER_COLOR0] = "color0",
239   [BUFFER_COLOR1] = "color1",
240   [BUFFER_COLOR2] = "color2",
241   [BUFFER_COLOR3] = "color3",
242   [BUFFER_COLOR4] = "color4",
243   [BUFFER_COLOR5] = "color5",
244   [BUFFER_COLOR6] = "color6",
245   [BUFFER_COLOR7] = "color7",
246};
247
248/**
249 * Called by ctx->Driver.Clear.
250 */
251static void
252intelClear(GLcontext *ctx, GLbitfield mask)
253{
254   struct intel_context *intel = intel_context(ctx);
255   const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
256   GLbitfield tri_mask = 0;
257   GLbitfield blit_mask = 0;
258   GLbitfield swrast_mask = 0;
259   struct gl_framebuffer *fb = ctx->DrawBuffer;
260   GLuint i;
261
262   if (0)
263      fprintf(stderr, "%s\n", __FUNCTION__);
264
265   /* HW color buffers (front, back, aux, generic FBO, etc) */
266   if (colorMask == ~0) {
267      /* clear all R,G,B,A */
268      /* XXX FBO: need to check if colorbuffers are software RBOs! */
269      blit_mask |= (mask & BUFFER_BITS_COLOR);
270   }
271   else {
272      /* glColorMask in effect */
273      tri_mask |= (mask & BUFFER_BITS_COLOR);
274   }
275
276   /* HW stencil */
277   if (mask & BUFFER_BIT_STENCIL) {
278      const struct intel_region *stencilRegion
279         = intel_get_rb_region(fb, BUFFER_STENCIL);
280      if (stencilRegion) {
281         /* have hw stencil */
282         if (IS_965(intel->intelScreen->deviceID) ||
283	     (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
284	    /* We have to use the 3D engine if we're clearing a partial mask
285	     * of the stencil buffer, or if we're on a 965 which has a tiled
286	     * depth/stencil buffer in a layout we can't blit to.
287	     */
288            tri_mask |= BUFFER_BIT_STENCIL;
289         }
290         else {
291            /* clearing all stencil bits, use blitting */
292            blit_mask |= BUFFER_BIT_STENCIL;
293         }
294      }
295   }
296
297   /* HW depth */
298   if (mask & BUFFER_BIT_DEPTH) {
299      /* clear depth with whatever method is used for stencil (see above) */
300      if (IS_965(intel->intelScreen->deviceID) ||
301	  tri_mask & BUFFER_BIT_STENCIL)
302         tri_mask |= BUFFER_BIT_DEPTH;
303      else
304         blit_mask |= BUFFER_BIT_DEPTH;
305   }
306
307   /* If we're doing a tri pass for depth/stencil, include a likely color
308    * buffer with it.
309    */
310   if (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
311      tri_mask |= blit_mask & BUFFER_BIT_BACK_LEFT;
312      blit_mask &= ~BUFFER_BIT_BACK_LEFT;
313   }
314
315   /* SW fallback clearing */
316   swrast_mask = mask & ~tri_mask & ~blit_mask;
317
318   for (i = 0; i < BUFFER_COUNT; i++) {
319      GLuint bufBit = 1 << i;
320      if ((blit_mask | tri_mask) & bufBit) {
321         if (!fb->Attachment[i].Renderbuffer->ClassID) {
322            blit_mask &= ~bufBit;
323            tri_mask &= ~bufBit;
324            swrast_mask |= bufBit;
325         }
326      }
327   }
328
329   if (blit_mask) {
330      if (INTEL_DEBUG & DEBUG_BLIT) {
331	 DBG("blit clear:");
332	 for (i = 0; i < BUFFER_COUNT; i++) {
333	    if (blit_mask & (1 << i))
334	       DBG(" %s", buffer_names[i]);
335	 }
336	 DBG("\n");
337      }
338      intelClearWithBlit(ctx, blit_mask);
339   }
340
341   if (tri_mask) {
342      if (INTEL_DEBUG & DEBUG_BLIT) {
343	 DBG("tri clear:");
344	 for (i = 0; i < BUFFER_COUNT; i++) {
345	    if (tri_mask & (1 << i))
346	       DBG(" %s", buffer_names[i]);
347	 }
348	 DBG("\n");
349      }
350      intel_clear_tris(ctx, tri_mask);
351   }
352
353   if (swrast_mask) {
354      if (INTEL_DEBUG & DEBUG_BLIT) {
355	 DBG("swrast clear:");
356	 for (i = 0; i < BUFFER_COUNT; i++) {
357	    if (swrast_mask & (1 << i))
358	       DBG(" %s", buffer_names[i]);
359	 }
360	 DBG("\n");
361      }
362      _swrast_Clear(ctx, swrast_mask);
363   }
364}
365
366
367void
368intelInitClearFuncs(struct dd_function_table *functions)
369{
370   functions->Clear = intelClear;
371}
372