diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_blit.c | 297 |
1 files changed, 123 insertions, 174 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 72b6e1acb97..45464e45d28 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -212,10 +212,8 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) struct intel_context *intel = intel_context(ctx); struct gl_framebuffer *fb = ctx->DrawBuffer; GLuint clear_depth; - GLbitfield skipBuffers = 0; - unsigned int num_cliprects; - struct drm_clip_rect *cliprects; - int x_off, y_off; + GLboolean all; + GLint cx, cy, cw, ch; BATCH_LOCALS; /* @@ -229,183 +227,134 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; } - /* If clearing both depth and stencil, skip BUFFER_BIT_STENCIL in - * the loop below. - */ - if ((mask & BUFFER_BIT_DEPTH) && (mask & BUFFER_BIT_STENCIL)) { - skipBuffers = BUFFER_BIT_STENCIL; - } - - intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off); - if (num_cliprects) { - GLint cx, cy, cw, ch; - drm_clip_rect_t clear; - int i; - - /* Get clear bounds after locking */ - cx = fb->_Xmin; + cx = fb->_Xmin; + if (fb->Name == 0) cy = fb->_Ymin; - cw = fb->_Xmax - cx; - ch = fb->_Ymax - cy; - - if (fb->Name == 0) { - /* clearing a window */ - - /* flip top to bottom */ - clear.x1 = cx + x_off; - clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch; - clear.x2 = clear.x1 + cw; - clear.y2 = clear.y1 + ch; - } - else { - /* clearing FBO */ - assert(num_cliprects == 1); - assert(cliprects == &intel->fboRect); - clear.x1 = cx; - clear.y1 = cy; - clear.x2 = clear.x1 + cw; - clear.y2 = clear.y1 + ch; - /* no change to mask */ + else + cy = ctx->DrawBuffer->Height - fb->_Ymax; + cw = fb->_Xmax - fb->_Xmin; + ch = fb->_Ymax - fb->_Ymin; + + if (cw == 0 || ch == 0) + return; + + GLuint buf; + all = (cw == fb->Width && ch == fb->Height); + + /* Loop over all renderbuffers */ + for (buf = 0; buf < BUFFER_COUNT && mask; buf++) { + const GLbitfield bufBit = 1 << buf; + struct intel_renderbuffer *irb; + drm_intel_bo *write_buffer; + int x1, y1, x2, y2; + uint32_t clear_val; + uint32_t BR13, CMD; + int pitch, cpp; + + if (!(mask & bufBit)) + continue; + + /* OK, clear this renderbuffer */ + irb = intel_get_renderbuffer(fb, buf); + write_buffer = intel_region_buffer(intel, irb->region, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); + x1 = cx + irb->region->draw_x; + y1 = cy + irb->region->draw_y; + x2 = cx + cw + irb->region->draw_x; + y2 = cy + ch + irb->region->draw_y; + + pitch = irb->region->pitch; + cpp = irb->region->cpp; + + DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n", + __FUNCTION__, + irb->region->buffer, (pitch * cpp), + x1, y1, x2 - x1, y2 - y1); + + BR13 = 0xf0 << 16; + CMD = XY_COLOR_BLT_CMD; + + /* Setup the blit command */ + if (cpp == 4) { + BR13 |= BR13_8888; + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + if (mask & BUFFER_BIT_DEPTH) + CMD |= XY_BLT_WRITE_RGB; + if (mask & BUFFER_BIT_STENCIL) + CMD |= XY_BLT_WRITE_ALPHA; + } else { + /* clearing RGBA */ + CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; + } + } else { + ASSERT(cpp == 2); + BR13 |= BR13_565; } - for (i = 0; i < num_cliprects; i++) { - const drm_clip_rect_t *box = &cliprects[i]; - drm_clip_rect_t b; - GLuint buf; - GLuint clearMask = mask; /* use copy, since we modify it below */ - GLboolean all = (cw == fb->Width && ch == fb->Height); - - if (!all) { - intel_intersect_cliprects(&b, &clear, box); - } - else { - b = *box; - } - - if (b.x1 >= b.x2 || b.y1 >= b.y2) - continue; - - if (0) - _mesa_printf("clear %d,%d..%d,%d, mask %x\n", - b.x1, b.y1, b.x2, b.y2, mask); - - /* Loop over all renderbuffers */ - for (buf = 0; buf < BUFFER_COUNT && clearMask; buf++) { - const GLbitfield bufBit = 1 << buf; - if ((clearMask & bufBit) && !(bufBit & skipBuffers)) { - /* OK, clear this renderbuffer */ - struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, buf); - dri_bo *write_buffer = - intel_region_buffer(intel, irb->region, - all ? INTEL_WRITE_FULL : - INTEL_WRITE_PART); - int x1 = b.x1 + irb->region->draw_x; - int y1 = b.y1 + irb->region->draw_y; - int x2 = b.x2 + irb->region->draw_x; - int y2 = b.y2 + irb->region->draw_y; - - GLuint clearVal; - GLint pitch, cpp; - GLuint BR13, CMD; - - pitch = irb->region->pitch; - cpp = irb->region->cpp; - - DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n", - __FUNCTION__, - irb->region->buffer, (pitch * cpp), - x1, y1, x2 - x1, y2 - y1); - - BR13 = 0xf0 << 16; - CMD = XY_COLOR_BLT_CMD; - - /* Setup the blit command */ - if (cpp == 4) { - BR13 |= BR13_8888; - if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { - if (clearMask & BUFFER_BIT_DEPTH) - CMD |= XY_BLT_WRITE_RGB; - if (clearMask & BUFFER_BIT_STENCIL) - CMD |= XY_BLT_WRITE_ALPHA; - } - else { - /* clearing RGBA */ - CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; - } - } - else { - ASSERT(cpp == 2); - BR13 |= BR13_565; - } - - assert(irb->region->tiling != I915_TILING_Y); + assert(irb->region->tiling != I915_TILING_Y); #ifndef I915 - if (irb->region->tiling != I915_TILING_NONE) { - CMD |= XY_DST_TILED; - pitch /= 4; - } + if (irb->region->tiling != I915_TILING_NONE) { + CMD |= XY_DST_TILED; + pitch /= 4; + } #endif - BR13 |= (pitch * cpp); - - if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { - clearVal = clear_depth; - } - else { - uint8_t clear[4]; - GLclampf *color = ctx->Color.ClearColor; - - CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); - CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); - CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); - CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); - - switch (irb->Base.Format) { - case MESA_FORMAT_ARGB8888: - case MESA_FORMAT_XRGB8888: - clearVal = PACK_COLOR_8888(clear[3], clear[0], - clear[1], clear[2]); - break; - case MESA_FORMAT_RGB565: - clearVal = PACK_COLOR_565(clear[0], clear[1], clear[2]); - break; - case MESA_FORMAT_ARGB4444: - clearVal = PACK_COLOR_4444(clear[3], clear[0], - clear[1], clear[2]); - break; - case MESA_FORMAT_ARGB1555: - clearVal = PACK_COLOR_1555(clear[3], clear[0], - clear[1], clear[2]); - break; - default: - _mesa_problem(ctx, "Unexpected renderbuffer format: %d\n", - irb->Base.Format); - clearVal = 0; - } - } - - /* - _mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n", - buf, irb->Base.Name); - */ - - assert(x1 < x2); - assert(y1 < y2); - - BEGIN_BATCH(6); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((y1 << 16) | x1); - OUT_BATCH((y2 << 16) | x2); - OUT_RELOC(write_buffer, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - 0); - OUT_BATCH(clearVal); - ADVANCE_BATCH(); - clearMask &= ~bufBit; /* turn off bit, for faster loop exit */ - } - } + BR13 |= (pitch * cpp); + + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + clear_val = clear_depth; + } else { + uint8_t clear[4]; + GLclampf *color = ctx->Color.ClearColor; + + CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); + + switch (irb->Base.Format) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + clear_val = PACK_COLOR_8888(clear[3], clear[0], + clear[1], clear[2]); + break; + case MESA_FORMAT_RGB565: + clear_val = PACK_COLOR_565(clear[0], clear[1], clear[2]); + break; + case MESA_FORMAT_ARGB4444: + clear_val = PACK_COLOR_4444(clear[3], clear[0], + clear[1], clear[2]); + break; + case MESA_FORMAT_ARGB1555: + clear_val = PACK_COLOR_1555(clear[3], clear[0], + clear[1], clear[2]); + break; + default: + _mesa_problem(ctx, "Unexpected renderbuffer format: %d\n", + irb->Base.Format); + clear_val = 0; + } } + + assert(x1 < x2); + assert(y1 < y2); + + BEGIN_BATCH(6); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((y1 << 16) | x1); + OUT_BATCH((y2 << 16) | x2); + OUT_RELOC(write_buffer, + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, + 0); + OUT_BATCH(clear_val); + ADVANCE_BATCH(); + + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) + mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); + else + mask &= ~bufBit; /* turn off bit, for faster loop exit */ } } |