/** * Clear the rasterizer's current color tile. * This is a bin command called during bin processing. * Clear commands always clear all bound layers. */ static void lp_rast_clear_color(struct lp_rasterizer_task *task, const union lp_rast_cmd_arg arg) { const struct lp_scene *scene = task->scene; unsigned cbuf = arg.clear_rb->cbuf; union util_color uc; enum pipe_format format; /* we never bin clear commands for non-existing buffers */ assert(cbuf < scene->fb.nr_cbufs); assert(scene->fb.cbufs[cbuf]); format = scene->fb.cbufs[cbuf]->format; uc = arg.clear_rb->color_val; /* * this is pretty rough since we have target format (bunch of bytes...) here. * dump it as raw 4 dwords. */ LP_DBG(DEBUG_RAST, "%s clear value (target format %d) raw 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, format, uc.ui[0], uc.ui[1], uc.ui[2], uc.ui[3]); util_fill_box(scene->cbufs[cbuf].map, format, scene->cbufs[cbuf].stride, scene->cbufs[cbuf].layer_stride, task->x, task->y, 0, task->width, task->height, scene->fb_max_layer + 1, &uc); /* this will increase for each rb which probably doesn't mean much */ LP_COUNT(nr_color_tile_clear); }
/** * Fallback for pipe->clear_render_target() function. * XXX this looks too hackish to be really useful. * cpp > 4 looks like a gross hack at best... * Plus can't use these transfer fallbacks when clearing * multisampled surfaces for instance. * Clears all bound layers. */ void util_clear_render_target(struct pipe_context *pipe, struct pipe_surface *dst, const union pipe_color_union *color, unsigned dstx, unsigned dsty, unsigned width, unsigned height) { struct pipe_transfer *dst_trans; ubyte *dst_map; union util_color uc; unsigned max_layer; assert(dst->texture); if (!dst->texture) return; if (dst->texture->target == PIPE_BUFFER) { /* * The fill naturally works on the surface format, however * the transfer uses resource format which is just bytes for buffers. */ unsigned dx, w; unsigned pixstride = util_format_get_blocksize(dst->format); dx = (dst->u.buf.first_element + dstx) * pixstride; w = width * pixstride; max_layer = 0; dst_map = pipe_transfer_map(pipe, dst->texture, 0, 0, PIPE_TRANSFER_WRITE, dx, 0, w, 1, &dst_trans); } else { max_layer = dst->u.tex.last_layer - dst->u.tex.first_layer; dst_map = pipe_transfer_map_3d(pipe, dst->texture, dst->u.tex.level, PIPE_TRANSFER_WRITE, dstx, dsty, dst->u.tex.first_layer, width, height, max_layer + 1, &dst_trans); } assert(dst_map); if (dst_map) { enum pipe_format format = dst->format; assert(dst_trans->stride > 0); if (util_format_is_pure_integer(format)) { /* * We expect int/uint clear values here, though some APIs * might disagree (but in any case util_pack_color() * couldn't handle it)... */ if (util_format_is_pure_sint(format)) { util_format_write_4i(format, color->i, 0, &uc, 0, 0, 0, 1, 1); } else { assert(util_format_is_pure_uint(format)); util_format_write_4ui(format, color->ui, 0, &uc, 0, 0, 0, 1, 1); } } else { util_pack_color(color->f, format, &uc); } util_fill_box(dst_map, dst->format, dst_trans->stride, dst_trans->layer_stride, 0, 0, 0, width, height, max_layer + 1, &uc); pipe->transfer_unmap(pipe, dst_trans); } }