radeon: add support for new ttm
[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_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_DEPTH] = "depth",
251 [BUFFER_STENCIL] = "stencil",
252 [BUFFER_ACCUM] = "accum",
253 [BUFFER_AUX0] = "aux0",
254 [BUFFER_COLOR0] = "color0",
255 [BUFFER_COLOR1] = "color1",
256 [BUFFER_COLOR2] = "color2",
257 [BUFFER_COLOR3] = "color3",
258 [BUFFER_COLOR4] = "color4",
259 [BUFFER_COLOR5] = "color5",
260 [BUFFER_COLOR6] = "color6",
261 [BUFFER_COLOR7] = "color7",
262 };
263
264 /**
265 * Called by ctx->Driver.Clear.
266 */
267 static void
268 intelClear(GLcontext *ctx, GLbitfield mask)
269 {
270 struct intel_context *intel = intel_context(ctx);
271 const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
272 GLbitfield tri_mask = 0;
273 GLbitfield blit_mask = 0;
274 GLbitfield swrast_mask = 0;
275 struct gl_framebuffer *fb = ctx->DrawBuffer;
276 GLuint i;
277
278 if (0)
279 fprintf(stderr, "%s\n", __FUNCTION__);
280
281 /* HW color buffers (front, back, aux, generic FBO, etc) */
282 if (colorMask == ~0) {
283 /* clear all R,G,B,A */
284 /* XXX FBO: need to check if colorbuffers are software RBOs! */
285 blit_mask |= (mask & BUFFER_BITS_COLOR);
286 }
287 else {
288 /* glColorMask in effect */
289 tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
290 }
291
292 /* HW stencil */
293 if (mask & BUFFER_BIT_STENCIL) {
294 const struct intel_region *stencilRegion
295 = intel_get_rb_region(fb, BUFFER_STENCIL);
296 if (stencilRegion) {
297 /* have hw stencil */
298 if (IS_965(intel->intelScreen->deviceID) ||
299 (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
300 /* We have to use the 3D engine if we're clearing a partial mask
301 * of the stencil buffer, or if we're on a 965 which has a tiled
302 * depth/stencil buffer in a layout we can't blit to.
303 */
304 tri_mask |= BUFFER_BIT_STENCIL;
305 }
306 else {
307 /* clearing all stencil bits, use blitting */
308 blit_mask |= BUFFER_BIT_STENCIL;
309 }
310 }
311 }
312
313 /* HW depth */
314 if (mask & BUFFER_BIT_DEPTH) {
315 /* clear depth with whatever method is used for stencil (see above) */
316 if (IS_965(intel->intelScreen->deviceID) ||
317 tri_mask & BUFFER_BIT_STENCIL)
318 tri_mask |= BUFFER_BIT_DEPTH;
319 else
320 blit_mask |= BUFFER_BIT_DEPTH;
321 }
322
323 /* If we're doing a tri pass for depth/stencil, include a likely color
324 * buffer with it.
325 */
326 if (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
327 int color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
328 if (color_bit != 0) {
329 tri_mask |= blit_mask & (1 << (color_bit - 1));
330 blit_mask &= ~(1 << (color_bit - 1));
331 }
332 }
333
334 /* SW fallback clearing */
335 swrast_mask = mask & ~tri_mask & ~blit_mask;
336
337 for (i = 0; i < BUFFER_COUNT; i++) {
338 GLuint bufBit = 1 << i;
339 if ((blit_mask | tri_mask) & bufBit) {
340 if (!fb->Attachment[i].Renderbuffer->ClassID) {
341 blit_mask &= ~bufBit;
342 tri_mask &= ~bufBit;
343 swrast_mask |= bufBit;
344 }
345 }
346 }
347
348 if (blit_mask) {
349 if (INTEL_DEBUG & DEBUG_BLIT) {
350 DBG("blit clear:");
351 for (i = 0; i < BUFFER_COUNT; i++) {
352 if (blit_mask & (1 << i))
353 DBG(" %s", buffer_names[i]);
354 }
355 DBG("\n");
356 }
357 intelClearWithBlit(ctx, blit_mask);
358 }
359
360 if (tri_mask) {
361 if (INTEL_DEBUG & DEBUG_BLIT) {
362 DBG("tri clear:");
363 for (i = 0; i < BUFFER_COUNT; i++) {
364 if (tri_mask & (1 << i))
365 DBG(" %s", buffer_names[i]);
366 }
367 DBG("\n");
368 }
369 intel_clear_tris(ctx, tri_mask);
370 }
371
372 if (swrast_mask) {
373 if (INTEL_DEBUG & DEBUG_BLIT) {
374 DBG("swrast clear:");
375 for (i = 0; i < BUFFER_COUNT; i++) {
376 if (swrast_mask & (1 << i))
377 DBG(" %s", buffer_names[i]);
378 }
379 DBG("\n");
380 }
381 _swrast_Clear(ctx, swrast_mask);
382 }
383 }
384
385
386 void
387 intelInitClearFuncs(struct dd_function_table *functions)
388 {
389 functions->Clear = intelClear;
390 }