summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJuan A. Suarez Romero <jasuarez@igalia.com>2020-12-18 11:33:15 +0100
committerMarge Bot <eric+marge@anholt.net>2021-01-13 12:49:37 +0000
commitf58a11460dddf771b5b35bbb1ee5de4b588b4d21 (patch)
tree7895c909a59026cadfb989ec62c81119a9d99f58 /src
parent79bf06605d55e94cc8d2ad9f7c787779f679b092 (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.c44
-rw-r--r--src/gallium/drivers/v3d/v3dx_rcl.c38
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))