diff options
author | Juan A. Suarez Romero <jasuarez@igalia.com> | 2020-12-18 11:33:15 +0100 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2021-01-13 12:49:37 +0000 |
commit | f58a11460dddf771b5b35bbb1ee5de4b588b4d21 (patch) | |
tree | 7895c909a59026cadfb989ec62c81119a9d99f58 /src | |
parent | 79bf06605d55e94cc8d2ad9f7c787779f679b092 (diff) |
v3d: add fast-path tile-based blit for depth/stencil buffers
This extends the TLB based blit to support both depth and stencil
buffers.
v2:
- Ammend comment for further clarification (Iago)
- Remove parenthesis (Iago)
- Remove condition so separate stencil blit is done (Iago)
Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8304>
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/v3d/v3d_blit.c | 44 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3dx_rcl.c | 38 |
2 files changed, 51 insertions, 31 deletions
diff --git a/src/gallium/drivers/v3d/v3d_blit.c b/src/gallium/drivers/v3d/v3d_blit.c index 4e96c183513..dd5805d55a3 100644 --- a/src/gallium/drivers/v3d/v3d_blit.c +++ b/src/gallium/drivers/v3d/v3d_blit.c @@ -416,11 +416,18 @@ v3d_tlb_blit(struct pipe_context *pctx, struct pipe_blit_info *info) struct v3d_context *v3d = v3d_context(pctx); struct v3d_screen *screen = v3d->screen; - if (screen->devinfo.ver < 40) + if (screen->devinfo.ver < 40 || !info->mask) return; - if ((info->mask & PIPE_MASK_RGBA) == 0) - return; + bool is_color_blit = info->mask & PIPE_MASK_RGBA; + bool is_depth_blit = info->mask & PIPE_MASK_Z; + bool is_stencil_blit = info->mask & PIPE_MASK_S; + + /* We should receive either a depth/stencil blit, or color blit, but + * not both. + */ + assert ((is_color_blit && !is_depth_blit && !is_stencil_blit) || + (!is_color_blit && (is_depth_blit || is_stencil_blit))); if (info->scissor_enable) return; @@ -431,7 +438,8 @@ v3d_tlb_blit(struct pipe_context *pctx, struct pipe_blit_info *info) info->src.box.height != info->dst.box.height) return; - if (util_format_is_depth_or_stencil(info->dst.resource->format)) + if (is_color_blit && + util_format_is_depth_or_stencil(info->dst.resource->format)) return; if (!v3d_rt_format_supported(&screen->devinfo, info->src.resource->format)) @@ -458,10 +466,11 @@ v3d_tlb_blit(struct pipe_context *pctx, struct pipe_blit_info *info) v3d_get_blit_surface(pctx, info->src.resource, info->src.level, info->src.box.z); struct pipe_surface *surfaces[V3D_MAX_DRAW_BUFFERS] = { 0 }; - surfaces[0] = dst_surf; + if (is_color_blit) + surfaces[0] = dst_surf; uint32_t tile_width, tile_height, max_bpp; - v3d_get_tile_buffer_size(msaa, 1, surfaces, src_surf, &tile_width, &tile_height, &max_bpp); + v3d_get_tile_buffer_size(msaa, is_color_blit ? 1 : 0, surfaces, src_surf, &tile_width, &tile_height, &max_bpp); int dst_surface_width = u_minify(info->dst.resource->width0, info->dst.level); @@ -478,7 +487,11 @@ v3d_tlb_blit(struct pipe_context *pctx, struct pipe_blit_info *info) return; } - struct v3d_job *job = v3d_get_job(v3d, 1u, surfaces, NULL, src_surf); + struct v3d_job *job = v3d_get_job(v3d, + is_color_blit ? 1u : 0u, + surfaces, + is_color_blit ? NULL : dst_surf, + src_surf); job->msaa = msaa; job->tile_width = tile_width; job->tile_height = tile_height; @@ -495,17 +508,28 @@ v3d_tlb_blit(struct pipe_context *pctx, struct pipe_blit_info *info) job->tile_height); job->needs_flush = true; - job->store |= PIPE_CLEAR_COLOR0; job->num_layers = info->dst.box.depth; + job->store = 0; + if (is_color_blit) { + job->store |= PIPE_CLEAR_COLOR0; + info->mask &= ~PIPE_MASK_RGBA; + } + if (is_depth_blit) { + job->store |= PIPE_CLEAR_DEPTH; + info->mask &= ~PIPE_MASK_Z; + } + if (is_stencil_blit){ + job->store |= PIPE_CLEAR_STENCIL; + info->mask &= ~PIPE_MASK_S; + } + v3d41_start_binning(v3d, job); v3d_job_submit(v3d, job); pipe_surface_reference(&dst_surf, NULL); pipe_surface_reference(&src_surf, NULL); - - info->mask &= ~PIPE_MASK_RGBA; } /* Optimal hardware path for blitting pixels. diff --git a/src/gallium/drivers/v3d/v3dx_rcl.c b/src/gallium/drivers/v3d/v3dx_rcl.c index 0da01055114..3ecc054a49d 100644 --- a/src/gallium/drivers/v3d/v3dx_rcl.c +++ b/src/gallium/drivers/v3d/v3dx_rcl.c @@ -115,7 +115,7 @@ store_general(struct v3d_job *job, struct v3d_cl *cl, struct pipe_surface *psurf, int layer, int buffer, int pipe_bit, uint32_t *stores_pending, bool general_color_clear, - bool is_blit) + bool resolve_4x) { struct v3d_surface *surf = v3d_surface(psurf); bool separate_stencil = surf->separate_stencil && buffer == STENCIL; @@ -159,10 +159,10 @@ store_general(struct v3d_job *job, store.height_in_ub_or_stride = slice->stride; } - assert(!is_blit || job->bbuf); + assert(!resolve_4x || job->bbuf); if (psurf->texture->nr_samples > 1) store.decimate_mode = V3D_DECIMATE_MODE_ALL_SAMPLES; - else if (is_blit && job->bbuf->texture->nr_samples > 1) + else if (resolve_4x && job->bbuf->texture->nr_samples > 1) store.decimate_mode = V3D_DECIMATE_MODE_4X; else store.decimate_mode = V3D_DECIMATE_MODE_SAMPLE_0; @@ -216,22 +216,23 @@ zs_buffer_from_pipe_bits(int pipe_clear_bits) static void v3d_rcl_emit_loads(struct v3d_job *job, struct v3d_cl *cl, int layer) { - uint32_t loads_pending = job->load; - uint32_t blit_pending = job->bbuf ? PIPE_CLEAR_COLOR0 : 0; - - assert(!job->bbuf || V3D_VERSION >= 40); - - /* When blitting, no color buffer is loaded; instead the blit source - * buffer is loaded. + /* When blitting, no color or zs buffer is loaded; instead the blit + * source buffer is loaded for the aspects that we are going to blit. */ assert(!job->bbuf || job->load == 0); + assert(!job->bbuf || job->nr_cbufs <= 1); + assert(!job->bbuf || V3D_VERSION >= 40); + + uint32_t loads_pending = job->bbuf ? job->store : job->load; for (int i = 0; i < job->nr_cbufs; i++) { uint32_t bit = PIPE_CLEAR_COLOR0 << i; if (!(loads_pending & bit)) continue; - struct pipe_surface *psurf = job->cbufs[i]; + struct pipe_surface *psurf = job->bbuf ? job->bbuf : job->cbufs[i]; + assert(!job->bbuf || i == 0); + if (!psurf || (V3D_VERSION < 40 && psurf->texture->nr_samples <= 1)) { continue; @@ -241,27 +242,22 @@ v3d_rcl_emit_loads(struct v3d_job *job, struct v3d_cl *cl, int layer) bit, &loads_pending); } - if (blit_pending) { - load_general(cl, job->bbuf, RENDER_TARGET_0, layer, - PIPE_CLEAR_COLOR0, &blit_pending); - assert(blit_pending == 0); - } - if ((loads_pending & PIPE_CLEAR_DEPTHSTENCIL) && (V3D_VERSION >= 40 || (job->zsbuf && job->zsbuf->texture->nr_samples > 1))) { - struct v3d_resource *rsc = v3d_resource(job->zsbuf->texture); + struct pipe_surface *src = job->bbuf ? job->bbuf : job->zsbuf; + struct v3d_resource *rsc = v3d_resource(src->texture); if (rsc->separate_stencil && (loads_pending & PIPE_CLEAR_STENCIL)) { - load_general(cl, job->zsbuf, + load_general(cl, src, STENCIL, layer, PIPE_CLEAR_STENCIL, &loads_pending); } if (loads_pending & PIPE_CLEAR_DEPTHSTENCIL) { - load_general(cl, job->zsbuf, + load_general(cl, src, zs_buffer_from_pipe_bits(loads_pending), layer, loads_pending & PIPE_CLEAR_DEPTHSTENCIL, @@ -331,7 +327,7 @@ v3d_rcl_emit_stores(struct v3d_job *job, struct v3d_cl *cl, int layer) * perspective. Non-MSAA surfaces will use * STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED. */ - assert(!job->bbuf || job->nr_cbufs == 1); + assert(!job->bbuf || job->nr_cbufs <= 1); for (int i = 0; i < job->nr_cbufs; i++) { uint32_t bit = PIPE_CLEAR_COLOR0 << i; if (!(job->store & bit)) |