mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-29 23:10:11 +01:00
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>
This commit is contained in:
parent
79bf06605d
commit
f58a11460d
2 changed files with 51 additions and 31 deletions
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue