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