/** * 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. */ 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; void *dst_map; union util_color uc; assert(dst->texture); if (!dst->texture) return; /* XXX: should handle multiple layers */ dst_map = pipe_transfer_map(pipe, dst->texture, dst->u.tex.level, dst->u.tex.first_layer, PIPE_TRANSFER_WRITE, dstx, dsty, width, height, &dst_trans); assert(dst_map); if (dst_map) { assert(dst_trans->stride > 0); util_pack_color(color->f, dst->texture->format, &uc); util_fill_rect(dst_map, dst->texture->format, dst_trans->stride, 0, 0, width, height, &uc); pipe->transfer_unmap(pipe, dst_trans); } }
/** * Flush the tile cache: write all dirty tiles back to the transfer. * any tiles "flagged" as cleared will be "really" cleared. */ void lp_flush_tile_cache(struct llvmpipe_tile_cache *tc) { struct pipe_transfer *pt = tc->transfer; unsigned x, y; if(!pt) return; assert(tc->transfer_map); /* push the tile to all positions marked as clear */ for (y = 0; y < pt->height; y += TILE_SIZE) { for (x = 0; x < pt->width; x += TILE_SIZE) { struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE]; if(tile->status != LP_TILE_STATUS_UNDEFINED) { unsigned w = TILE_SIZE; unsigned h = TILE_SIZE; if (!pipe_clip_tile(x, y, &w, &h, pt)) { switch(tile->status) { case LP_TILE_STATUS_CLEAR: /* Actually clear the tiles which were flagged as being in a * clear state. */ util_fill_rect(tc->transfer_map, &pt->block, pt->stride, x, y, w, h, tc->clear_val); break; case LP_TILE_STATUS_DEFINED: lp_tile_write_4ub(pt->format, tile->color, tc->transfer_map, pt->stride, x, y, w, h); break; default: assert(0); break; } } tile->status = LP_TILE_STATUS_UNDEFINED; } } } }
PUBLIC Status XvMCClearSubpicture(Display *dpy, XvMCSubpicture *subpicture, short x, short y, unsigned short width, unsigned short height, unsigned int color) { XvMCSubpicturePrivate *subpicture_priv; XvMCContextPrivate *context_priv; struct pipe_context *pipe; struct pipe_sampler_view *dst; struct pipe_box dst_box = {x, y, 0, width, height, 1}; struct pipe_transfer *transfer; union util_color uc; void *map; assert(dpy); if (!subpicture) return XvMCBadSubpicture; /* Convert color to float */ util_format_read_4f(PIPE_FORMAT_B8G8R8A8_UNORM, uc.f, 1, &color, 4, 0, 0, 1, 1); subpicture_priv = subpicture->privData; context_priv = subpicture_priv->context->privData; pipe = context_priv->pipe; dst = subpicture_priv->sampler; /* TODO: Assert clear rect is within bounds? Or clip? */ transfer = pipe->get_transfer(pipe, dst->texture, 0, PIPE_TRANSFER_WRITE, &dst_box); if (!transfer) return XvMCBadSubpicture; map = pipe->transfer_map(pipe, transfer); if (map) { util_fill_rect(map, dst->texture->format, transfer->stride, 0, 0, dst_box.width, dst_box.height, &uc); pipe->transfer_unmap(pipe, transfer); } pipe->transfer_destroy(pipe, transfer); return Success; }
void util_fill_box(ubyte * dst, enum pipe_format format, unsigned stride, unsigned layer_stride, unsigned x, unsigned y, unsigned z, unsigned width, unsigned height, unsigned depth, union util_color *uc) { unsigned layer; dst += z * layer_stride; for (layer = z; layer < depth; layer++) { util_fill_rect(dst, format, stride, x, y, width, height, uc); dst += layer_stride; } }
/** * 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. */ 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; void *dst_map; union util_color uc; 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; dst_map = pipe_transfer_map(pipe, dst->texture, 0, 0, PIPE_TRANSFER_WRITE, dx, 0, w, 1, &dst_trans); } else { /* XXX: should handle multiple layers */ dst_map = pipe_transfer_map(pipe, dst->texture, dst->u.tex.level, dst->u.tex.first_layer, PIPE_TRANSFER_WRITE, dstx, dsty, width, height, &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, dst->format, &uc); } util_fill_rect(dst_map, dst->format, dst_trans->stride, 0, 0, width, height, &uc); pipe->transfer_unmap(pipe, dst_trans); } }
/** * Fallback for pipe->surface_fill() function. * XXX should probably put this in new u_surface.c file... */ void util_surface_fill(struct pipe_context *pipe, struct pipe_surface *dst, unsigned dstx, unsigned dsty, unsigned width, unsigned height, unsigned value) { struct pipe_screen *screen = pipe->screen; struct pipe_transfer *dst_trans; void *dst_map; assert(dst->texture); if (!dst->texture) return; dst_trans = screen->get_tex_transfer(screen, dst->texture, dst->face, dst->level, dst->zslice, PIPE_TRANSFER_WRITE, dstx, dsty, width, height); dst_map = pipe->screen->transfer_map(screen, dst_trans); assert(dst_map); if (dst_map) { assert(dst_trans->stride > 0); switch (util_format_get_blocksize(dst_trans->texture->format)) { case 1: case 2: case 4: util_fill_rect(dst_map, dst_trans->texture->format, dst_trans->stride, 0, 0, width, height, value); break; case 8: { /* expand the 4-byte clear value to an 8-byte value */ ushort *row = (ushort *) dst_map; ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff); ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff); ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff); ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff); unsigned i, j; val0 = (val0 << 8) | val0; val1 = (val1 << 8) | val1; val2 = (val2 << 8) | val2; val3 = (val3 << 8) | val3; for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { row[j*4+0] = val0; row[j*4+1] = val1; row[j*4+2] = val2; row[j*4+3] = val3; } row += dst_trans->stride/2; } } break; default: assert(0); break; } } pipe->screen->transfer_unmap(pipe->screen, dst_trans); screen->tex_transfer_destroy(dst_trans); }
/** * Clear the rasterizer's current color tile. * This is a bin command called during bin processing. */ 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; if (scene->fb.nr_cbufs) { unsigned i; union util_color uc; if (util_format_is_pure_integer(scene->fb.cbufs[0]->format)) { /* * We expect int/uint clear values here, though some APIs * might disagree (but in any case util_pack_color() * couldn't handle it)... */ LP_DBG(DEBUG_RAST, "%s pure int 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, arg.clear_color.ui[0], arg.clear_color.ui[1], arg.clear_color.ui[2], arg.clear_color.ui[3]); for (i = 0; i < scene->fb.nr_cbufs; i++) { enum pipe_format format = scene->fb.cbufs[i]->format; if (util_format_is_pure_sint(format)) { util_format_write_4i(format, arg.clear_color.i, 0, &uc, 0, 0, 0, 1, 1); } else { assert(util_format_is_pure_uint(format)); util_format_write_4ui(format, arg.clear_color.ui, 0, &uc, 0, 0, 0, 1, 1); } util_fill_rect(scene->cbufs[i].map, scene->fb.cbufs[i]->format, scene->cbufs[i].stride, task->x, task->y, TILE_SIZE, TILE_SIZE, &uc); } } else { uint8_t clear_color[4]; for (i = 0; i < 4; ++i) { clear_color[i] = float_to_ubyte(arg.clear_color.f[i]); } LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, clear_color[0], clear_color[1], clear_color[2], clear_color[3]); for (i = 0; i < scene->fb.nr_cbufs; i++) { util_pack_color(arg.clear_color.f, scene->fb.cbufs[i]->format, &uc); util_fill_rect(scene->cbufs[i].map, scene->fb.cbufs[i]->format, scene->cbufs[i].stride, task->x, task->y, TILE_SIZE, TILE_SIZE, &uc); } } } LP_COUNT(nr_color_tile_clear); }