Commit f58a1146 authored by Juan A. Suárez's avatar Juan A. Suárez Committed by Marge Bot

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. Suárez's avatarJuan A. Suarez Romero <jasuarez@igalia.com>
Reviewed-by: Iago Toral's avatarIago Toral Quiroga <itoral@igalia.com>
Part-of: <!8304>
parent 79bf0660
Pipeline #255273 waiting for manual action with stages
......@@ -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.
......
......@@ -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))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment