brw_clear.c revision 4451eb2e7533a41f67ed21d05a8d9ab5efec77e9
1/**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28#include "intel_clear.h"
29#include "intel_context.h"
30#include "intel_blit.h"
31#include "intel_buffers.h"
32#include "intel_chipset.h"
33#include "intel_fbo.h"
34#include "intel_regions.h"
35#include "intel_batchbuffer.h"
36#include "main/framebuffer.h"
37#include "swrast/swrast.h"
38#include "drirenderbuffer.h"
39
40#define FILE_DEBUG_FLAG DEBUG_BLIT
41
42/* A true meta version of this would be very simple and additionally
43 * machine independent.  Maybe we'll get there one day.
44 */
45static void
46intelClearWithTris(struct intel_context *intel, GLbitfield mask)
47{
48   GLcontext *ctx = &intel->ctx;
49   struct gl_framebuffer *fb = ctx->DrawBuffer;
50   GLuint buf;
51
52   intel->vtbl.install_meta_state(intel);
53
54   /* Back and stencil cliprects are the same.  Try and do both
55    * buffers at once:
56    */
57   if (mask & (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH)) {
58      struct intel_region *backRegion =
59	 intel_get_rb_region(fb, BUFFER_BACK_LEFT);
60      struct intel_region *depthRegion =
61	 intel_get_rb_region(fb, BUFFER_DEPTH);
62
63      intel->vtbl.meta_draw_region(intel, backRegion, depthRegion);
64
65      if (mask & BUFFER_BIT_BACK_LEFT)
66	 intel->vtbl.meta_color_mask(intel, GL_TRUE);
67      else
68	 intel->vtbl.meta_color_mask(intel, GL_FALSE);
69
70      if (mask & BUFFER_BIT_STENCIL)
71	 intel->vtbl.meta_stencil_replace(intel,
72					  intel->ctx.Stencil.WriteMask[0],
73					  intel->ctx.Stencil.Clear);
74      else
75	 intel->vtbl.meta_no_stencil_write(intel);
76
77      if (mask & BUFFER_BIT_DEPTH)
78	 intel->vtbl.meta_depth_replace(intel);
79      else
80	 intel->vtbl.meta_no_depth_write(intel);
81
82      intel->vtbl.meta_draw_quad(intel,
83				 fb->_Xmin,
84				 fb->_Xmax,
85				 fb->_Ymin,
86				 fb->_Ymax,
87				 intel->ctx.Depth.Clear,
88				 intel->ClearColor8888,
89				 0, 0, 0, 0);   /* texcoords */
90
91      mask &= ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH);
92   }
93
94   /* clear the remaining (color) renderbuffers */
95   for (buf = 0; buf < BUFFER_COUNT && mask; buf++) {
96      const GLuint bufBit = 1 << buf;
97      if (mask & bufBit) {
98	 struct intel_renderbuffer *irbColor =
99	    intel_renderbuffer(fb->Attachment[buf].Renderbuffer);
100
101	 ASSERT(irbColor);
102
103	 intel->vtbl.meta_no_depth_write(intel);
104	 intel->vtbl.meta_no_stencil_write(intel);
105	 intel->vtbl.meta_color_mask(intel, GL_TRUE);
106	 intel->vtbl.meta_draw_region(intel, irbColor->region, NULL);
107
108	 intel->vtbl.meta_draw_quad(intel,
109				    fb->_Xmin,
110				    fb->_Xmax,
111				    fb->_Ymin,
112				    fb->_Ymax,
113				    0, intel->ClearColor8888,
114				    0, 0, 0, 0);   /* texcoords */
115
116	 mask &= ~bufBit;
117      }
118   }
119
120   intel->vtbl.leave_meta_state(intel);
121}
122
123static const char *buffer_names[] = {
124   [BUFFER_FRONT_LEFT] = "front",
125   [BUFFER_BACK_LEFT] = "back",
126   [BUFFER_FRONT_RIGHT] = "front right",
127   [BUFFER_BACK_RIGHT] = "back right",
128   [BUFFER_AUX0] = "aux0",
129   [BUFFER_AUX1] = "aux1",
130   [BUFFER_AUX2] = "aux2",
131   [BUFFER_AUX3] = "aux3",
132   [BUFFER_DEPTH] = "depth",
133   [BUFFER_STENCIL] = "stencil",
134   [BUFFER_ACCUM] = "accum",
135   [BUFFER_COLOR0] = "color0",
136   [BUFFER_COLOR1] = "color1",
137   [BUFFER_COLOR2] = "color2",
138   [BUFFER_COLOR3] = "color3",
139   [BUFFER_COLOR4] = "color4",
140   [BUFFER_COLOR5] = "color5",
141   [BUFFER_COLOR6] = "color6",
142   [BUFFER_COLOR7] = "color7",
143};
144
145/**
146 * Called by ctx->Driver.Clear.
147 */
148static void
149intelClear(GLcontext *ctx, GLbitfield mask)
150{
151   struct intel_context *intel = intel_context(ctx);
152   const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
153   GLbitfield tri_mask = 0;
154   GLbitfield blit_mask = 0;
155   GLbitfield swrast_mask = 0;
156   struct gl_framebuffer *fb = ctx->DrawBuffer;
157   GLuint i;
158
159   if (0)
160      fprintf(stderr, "%s\n", __FUNCTION__);
161
162   /* HW color buffers (front, back, aux, generic FBO, etc) */
163   if (colorMask == ~0) {
164      /* clear all R,G,B,A */
165      /* XXX FBO: need to check if colorbuffers are software RBOs! */
166      blit_mask |= (mask & BUFFER_BITS_COLOR);
167   }
168   else {
169      /* glColorMask in effect */
170      tri_mask |= (mask & BUFFER_BITS_COLOR);
171   }
172
173   /* HW stencil */
174   if (mask & BUFFER_BIT_STENCIL) {
175      const struct intel_region *stencilRegion
176         = intel_get_rb_region(fb, BUFFER_STENCIL);
177      if (stencilRegion) {
178         /* have hw stencil */
179         if (IS_965(intel->intelScreen->deviceID) ||
180	     (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
181	    /* We have to use the 3D engine if we're clearing a partial mask
182	     * of the stencil buffer, or if we're on a 965 which has a tiled
183	     * depth/stencil buffer in a layout we can't blit to.
184	     */
185            tri_mask |= BUFFER_BIT_STENCIL;
186         }
187         else {
188            /* clearing all stencil bits, use blitting */
189            blit_mask |= BUFFER_BIT_STENCIL;
190         }
191      }
192   }
193
194   /* HW depth */
195   if (mask & BUFFER_BIT_DEPTH) {
196      /* clear depth with whatever method is used for stencil (see above) */
197      if (IS_965(intel->intelScreen->deviceID) ||
198	  tri_mask & BUFFER_BIT_STENCIL)
199         tri_mask |= BUFFER_BIT_DEPTH;
200      else
201         blit_mask |= BUFFER_BIT_DEPTH;
202   }
203
204   /* SW fallback clearing */
205   swrast_mask = mask & ~tri_mask & ~blit_mask;
206
207   for (i = 0; i < BUFFER_COUNT; i++) {
208      GLuint bufBit = 1 << i;
209      if ((blit_mask | tri_mask) & bufBit) {
210         if (!fb->Attachment[i].Renderbuffer->ClassID) {
211            blit_mask &= ~bufBit;
212            tri_mask &= ~bufBit;
213            swrast_mask |= bufBit;
214         }
215      }
216   }
217
218   if (blit_mask) {
219      if (INTEL_DEBUG & DEBUG_BLIT) {
220	 DBG("blit clear:");
221	 for (i = 0; i < BUFFER_COUNT; i++) {
222	    if (blit_mask & (1 << i))
223	       DBG(" %s", buffer_names[i]);
224	 }
225	 DBG("\n");
226      }
227      intelClearWithBlit(ctx, blit_mask);
228   }
229
230   if (tri_mask) {
231      if (INTEL_DEBUG & DEBUG_BLIT) {
232	 DBG("tri clear:");
233	 for (i = 0; i < BUFFER_COUNT; i++) {
234	    if (tri_mask & (1 << i))
235	       DBG(" %s", buffer_names[i]);
236	 }
237	 DBG("\n");
238      }
239      intelClearWithTris(intel, tri_mask);
240   }
241
242   if (swrast_mask) {
243      if (INTEL_DEBUG & DEBUG_BLIT) {
244	 DBG("swrast clear:");
245	 for (i = 0; i < BUFFER_COUNT; i++) {
246	    if (swrast_mask & (1 << i))
247	       DBG(" %s", buffer_names[i]);
248	 }
249	 DBG("\n");
250      }
251      _swrast_Clear(ctx, swrast_mask);
252   }
253}
254
255
256void
257intelInitClearFuncs(struct dd_function_table *functions)
258{
259   functions->Clear = intelClear;
260}
261