v3d: support blitting straight from tile buffer

This allows us to handle blitting (including MSAA resolve) directly
from the tile buffer to memory. We will use this soon to provide a
faster implementation of TLB blits.

Reviewed-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30322>
This commit is contained in:
Iago Toral Quiroga
2024-07-18 09:15:20 +02:00
committed by Marge Bot
parent 9fbb11505a
commit 9a9f281251
2 changed files with 40 additions and 11 deletions

View File

@@ -378,11 +378,14 @@ struct v3d_job {
* Surfaces to submit rendering for.
* For blit operations, bbuf is the source surface, and cbufs[0] is
* the destination surface.
* For blit operations straight from the job's tile buffer, dbuf is the
* blit destination surface.
*/
uint32_t nr_cbufs;
struct pipe_surface *cbufs[V3D_MAX_DRAW_BUFFERS];
struct pipe_surface *zsbuf;
struct pipe_surface *bbuf;
struct pipe_surface *dbuf;
/** @} */
/** @{
* Bounding box of the scissor across all queued drawing.
@@ -453,6 +456,13 @@ struct v3d_job {
* (either clears or draws) and should be stored.
*/
uint32_t store;
/* Bitmask of PIPE_CLEAR_* of buffers that need to be blitted into
* a destination buffer other than the jobs RT. Used to implement
* blits from jobs that have not yet been flushed, including MSAA
* resolve.
*/
uint32_t blit_tlb;
uint32_t clear_color[V3D_MAX_DRAW_BUFFERS][4];
float clear_z;
uint8_t clear_s;

View File

@@ -97,7 +97,8 @@ store_general(struct v3d_job *job,
surf = v3d_surface(psurf);
}
*stores_pending &= ~pipe_bit;
if (stores_pending)
*stores_pending &= ~pipe_bit;
struct v3d_resource *rsc = v3d_resource(psurf->texture);
@@ -131,13 +132,18 @@ store_general(struct v3d_job *job,
store.height_in_ub_or_stride = slice->stride;
}
assert(!resolve_4x || job->bbuf);
if (psurf->texture->nr_samples > 1)
if (psurf->texture->nr_samples > 1) {
store.decimate_mode = V3D_DECIMATE_MODE_ALL_SAMPLES;
else if (resolve_4x && job->bbuf->texture->nr_samples > 1)
} else if (resolve_4x) {
/* We are resolving from a MSAA blit buffer or we are
* resolving directly from TLB to a resolve buffer
*/
assert((job->bbuf && job->bbuf->texture->nr_samples > 1) ||
(job->dbuf && job->dbuf->texture->nr_samples <= 1));
store.decimate_mode = V3D_DECIMATE_MODE_4X;
else
} else {
store.decimate_mode = V3D_DECIMATE_MODE_SAMPLE_0;
}
}
}
@@ -223,18 +229,31 @@ 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->dbuf) || job->nr_cbufs <= 1);
for (int i = 0; i < job->nr_cbufs; i++) {
uint32_t bit = PIPE_CLEAR_COLOR0 << i;
if (!(job->store & bit))
continue;
struct pipe_surface *psurf = job->cbufs[i];
if (!psurf)
continue;
uint32_t bit = PIPE_CLEAR_COLOR0 << i;
if (job->blit_tlb & bit) {
assert(job->dbuf);
bool blit_resolve =
job->dbuf->texture->nr_samples <= 1 &&
psurf->texture->nr_samples > 1;
store_general(job, cl, job->dbuf, layer,
RENDER_TARGET_0 + i, bit, NULL,
false, blit_resolve);
}
if (!(job->store & bit))
continue;
bool blit_resolve =
job->bbuf && job->bbuf->texture->nr_samples > 1 &&
psurf->texture->nr_samples <= 1;
store_general(job, cl, psurf, layer, RENDER_TARGET_0 + i, bit,
&stores_pending, general_color_clear, job->bbuf);
&stores_pending, general_color_clear, blit_resolve);
}
if (job->store & PIPE_CLEAR_DEPTHSTENCIL && job->zsbuf) {