diff options
author | Eric Anholt <eric@anholt.net> | 2015-04-06 15:12:58 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2015-04-13 23:20:46 -0700 |
commit | 1be329e64cd035e3ee088cff3a50d39e1ad66868 (patch) | |
tree | 5dc50073b69a5aa27ab9e083fec86feac6827392 /src/gallium/drivers/vc4/vc4_blit.c | |
parent | 76d56752ccff5bca3a0808705d5da76f186afb33 (diff) |
vc4: Add a blitter path using just the render thread.
This accelerates the path for generating the shadow tiled texture when
asked to sample from a raster texture (typical in glamor).
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_blit.c')
-rw-r--r-- | src/gallium/drivers/vc4/vc4_blit.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/gallium/drivers/vc4/vc4_blit.c b/src/gallium/drivers/vc4/vc4_blit.c index 5c98fb612e0..4f87189fd2e 100644 --- a/src/gallium/drivers/vc4/vc4_blit.c +++ b/src/gallium/drivers/vc4/vc4_blit.c @@ -26,6 +26,130 @@ #include "util/u_blitter.h" #include "vc4_context.h" +static void +vc4_tile_blit_color_rcl(struct vc4_context *vc4, + struct vc4_surface *dst_surf, + struct vc4_surface *src_surf) +{ + struct vc4_resource *src = vc4_resource(src_surf->base.texture); + struct vc4_resource *dst = vc4_resource(dst_surf->base.texture); + + uint32_t min_x_tile = 0; + uint32_t min_y_tile = 0; + uint32_t max_x_tile = (dst_surf->base.width - 1) / 64; + uint32_t max_y_tile = (dst_surf->base.height - 1) / 64; + uint32_t xtiles = max_x_tile - min_x_tile + 1; + uint32_t ytiles = max_y_tile - min_y_tile + 1; + uint32_t reloc_size = 9; + uint32_t config_size = 11 + reloc_size; + uint32_t loadstore_size = 7 + reloc_size; + uint32_t tilecoords_size = 3; + cl_ensure_space(&vc4->rcl, + config_size + + xtiles * ytiles * (loadstore_size * 2 + + tilecoords_size * 1)); + cl_ensure_space(&vc4->bo_handles, 2 * sizeof(uint32_t)); + cl_ensure_space(&vc4->bo_pointers, 2 * sizeof(struct vc4_bo *)); + + cl_start_reloc(&vc4->rcl, 1); + cl_u8(&vc4->rcl, VC4_PACKET_TILE_RENDERING_MODE_CONFIG); + cl_reloc(vc4, &vc4->rcl, dst->bo, dst_surf->offset); + cl_u16(&vc4->rcl, dst_surf->base.width); + cl_u16(&vc4->rcl, dst_surf->base.height); + cl_u16(&vc4->rcl, ((dst_surf->tiling << + VC4_RENDER_CONFIG_MEMORY_FORMAT_SHIFT) | + (vc4_rt_format_is_565(dst_surf->base.format) ? + VC4_RENDER_CONFIG_FORMAT_BGR565 : + VC4_RENDER_CONFIG_FORMAT_RGBA8888))); + + uint32_t src_hindex = vc4_gem_hindex(vc4, src->bo); + + for (int y = min_y_tile; y <= max_y_tile; y++) { + for (int x = min_x_tile; x <= max_x_tile; x++) { + bool end_of_frame = (x == max_x_tile && + y == max_y_tile); + + cl_start_reloc(&vc4->rcl, 1); + cl_u8(&vc4->rcl, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); + cl_u8(&vc4->rcl, + VC4_LOADSTORE_TILE_BUFFER_COLOR | + (src_surf->tiling << + VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT)); + cl_u8(&vc4->rcl, + vc4_rt_format_is_565(src_surf->base.format) ? + VC4_LOADSTORE_TILE_BUFFER_BGR565 : + VC4_LOADSTORE_TILE_BUFFER_RGBA8888); + cl_reloc_hindex(&vc4->rcl, src_hindex, + src_surf->offset); + + cl_u8(&vc4->rcl, VC4_PACKET_TILE_COORDINATES); + cl_u8(&vc4->rcl, x); + cl_u8(&vc4->rcl, y); + + if (end_of_frame) { + cl_u8(&vc4->rcl, + VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF); + } else { + cl_u8(&vc4->rcl, + VC4_PACKET_STORE_MS_TILE_BUFFER); + } + } + } + + vc4->draw_min_x = 0; + vc4->draw_min_y = 0; + vc4->draw_max_x = dst_surf->base.width; + vc4->draw_max_y = dst_surf->base.height; + + dst->writes++; + vc4->needs_flush = true; +} + +static struct vc4_surface * +vc4_get_blit_surface(struct pipe_context *pctx, + struct pipe_resource *prsc, unsigned level) +{ + struct pipe_surface tmpl; + + memset(&tmpl, 0, sizeof(tmpl)); + tmpl.format = prsc->format; + tmpl.u.tex.level = level; + tmpl.u.tex.first_layer = 0; + tmpl.u.tex.last_layer = 0; + + return vc4_surface(pctx->create_surface(pctx, prsc, &tmpl)); +} + +static bool +vc4_tile_blit(struct pipe_context *pctx, const struct pipe_blit_info *info) +{ + struct vc4_context *vc4 = vc4_context(pctx); + + if ((info->mask & PIPE_MASK_RGBA) == 0) + return false; + + if (info->dst.box.x != 0 || info->dst.box.y != 0 || + info->src.box.x != 0 || info->src.box.y != 0 || + info->dst.box.width != info->src.box.width || + info->dst.box.height != info->src.box.height) { + return false; + } + + struct vc4_surface *dst_surf = + vc4_get_blit_surface(pctx, info->dst.resource, info->dst.level); + struct vc4_surface *src_surf = + vc4_get_blit_surface(pctx, info->src.resource, info->src.level); + + vc4_flush(pctx); + vc4_tile_blit_color_rcl(vc4, dst_surf, src_surf); + vc4_job_submit(vc4); + + pctx->surface_destroy(pctx, &dst_surf->base); + pctx->surface_destroy(pctx, &src_surf->base); + + return true; +} + static bool vc4_render_blit(struct pipe_context *ctx, struct pipe_blit_info *info) { @@ -77,6 +201,9 @@ vc4_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info) return; } + if (vc4_tile_blit(pctx, blit_info)) + return; + if (util_try_blit_via_copy_region(pctx, &info)) { return; /* done */ } |