v3d: implement tile buffer blits
This implements blit operation using the TLB. It uses a source color buffer (bbuf) which will be blitted to color buffer 0. It also takes in account the number of samples for the input and output so it can perform multisample resolve. v1: - Fix comment (Iago) - Removed needless brackets (Iago) - Ensure msaa is correctly set (Iago) - Get rid of job->resolve (Iago) - Add rbuf as part of job's key (Iago) - Rename rbuf/rsurf by bbuf/bsurf (Iago) - Revert needless change (Iago) v2: - Remove spurious change (Iago) - Add assert for safety reasons (Iago) - Add brackets in condition (Iago) - Fix commit message and title (Iago) - Do tile blit only for version >=4.0 (Iago) v3: - Add assertion (Iago) - Fix comment (Iago) - Change commit title (Iago) Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7816>
This commit is contained in:
committed by
Marge Bot
parent
9eb2517a88
commit
487dd96c4f
@@ -280,6 +280,7 @@ struct v3d_ssbo_stateobj {
|
||||
struct v3d_job_key {
|
||||
struct pipe_surface *cbufs[4];
|
||||
struct pipe_surface *zsbuf;
|
||||
struct pipe_surface *bbuf;
|
||||
};
|
||||
|
||||
enum v3d_ez_state {
|
||||
@@ -336,10 +337,15 @@ struct v3d_job {
|
||||
/* Size of the submit.bo_handles array. */
|
||||
uint32_t bo_handles_size;
|
||||
|
||||
/** @{ Surfaces to submit rendering for. */
|
||||
/** @{
|
||||
* Surfaces to submit rendering for.
|
||||
* For blit operations, bbuf is the source surface, and cbufs[0] is
|
||||
* the destination surface.
|
||||
*/
|
||||
uint32_t nr_cbufs;
|
||||
struct pipe_surface *cbufs[4];
|
||||
struct pipe_surface *zsbuf;
|
||||
struct pipe_surface *bbuf;
|
||||
/** @} */
|
||||
/** @{
|
||||
* Bounding box of the scissor across all queued drawing.
|
||||
@@ -648,7 +654,8 @@ void v3d_job_free(struct v3d_context *v3d, struct v3d_job *job);
|
||||
struct v3d_job *v3d_get_job(struct v3d_context *v3d,
|
||||
uint32_t nr_cbufs,
|
||||
struct pipe_surface **cbufs,
|
||||
struct pipe_surface *zsbuf);
|
||||
struct pipe_surface *zsbuf,
|
||||
struct pipe_surface *bbuf);
|
||||
struct v3d_job *v3d_get_job_for_fbo(struct v3d_context *v3d);
|
||||
void v3d_job_set_tile_buffer_size(struct v3d_job *job);
|
||||
void v3d_job_add_bo(struct v3d_job *job, struct v3d_bo *bo);
|
||||
|
||||
@@ -72,6 +72,8 @@ v3d_job_free(struct v3d_context *v3d, struct v3d_job *job)
|
||||
job->zsbuf->texture);
|
||||
pipe_surface_reference(&job->zsbuf, NULL);
|
||||
}
|
||||
if (job->bbuf)
|
||||
pipe_surface_reference(&job->bbuf, NULL);
|
||||
|
||||
if (v3d->job == job)
|
||||
v3d->job = NULL;
|
||||
@@ -300,6 +302,13 @@ v3d_job_set_tile_buffer_size(struct v3d_job *job)
|
||||
max_bpp = MAX2(max_bpp, surf->internal_bpp);
|
||||
}
|
||||
}
|
||||
|
||||
if (job->bbuf) {
|
||||
struct v3d_surface *bsurf = v3d_surface(job->bbuf);
|
||||
assert(job->bbuf->texture->nr_samples <= 1 || job->msaa);
|
||||
max_bpp = MAX2(max_bpp, bsurf->internal_bpp);
|
||||
}
|
||||
|
||||
job->internal_bpp = max_bpp;
|
||||
STATIC_ASSERT(RENDER_TARGET_MAXIMUM_32BPP == 0);
|
||||
tile_size_index += max_bpp;
|
||||
@@ -321,7 +330,8 @@ struct v3d_job *
|
||||
v3d_get_job(struct v3d_context *v3d,
|
||||
uint32_t nr_cbufs,
|
||||
struct pipe_surface **cbufs,
|
||||
struct pipe_surface *zsbuf)
|
||||
struct pipe_surface *zsbuf,
|
||||
struct pipe_surface *bbuf)
|
||||
{
|
||||
/* Return the existing job for this FBO if we have one */
|
||||
struct v3d_job_key local_key = {
|
||||
@@ -332,6 +342,7 @@ v3d_get_job(struct v3d_context *v3d,
|
||||
cbufs[3],
|
||||
},
|
||||
.zsbuf = zsbuf,
|
||||
.bbuf = bbuf,
|
||||
};
|
||||
struct hash_entry *entry = _mesa_hash_table_search(v3d->jobs,
|
||||
&local_key);
|
||||
@@ -363,6 +374,11 @@ v3d_get_job(struct v3d_context *v3d,
|
||||
if (zsbuf->texture->nr_samples > 1)
|
||||
job->msaa = true;
|
||||
}
|
||||
if (bbuf) {
|
||||
pipe_surface_reference(&job->bbuf, bbuf);
|
||||
if (bbuf->texture->nr_samples > 1)
|
||||
job->msaa = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < job->nr_cbufs; i++) {
|
||||
if (cbufs[i])
|
||||
@@ -399,7 +415,7 @@ v3d_get_job_for_fbo(struct v3d_context *v3d)
|
||||
uint32_t nr_cbufs = v3d->framebuffer.nr_cbufs;
|
||||
struct pipe_surface **cbufs = v3d->framebuffer.cbufs;
|
||||
struct pipe_surface *zsbuf = v3d->framebuffer.zsbuf;
|
||||
struct v3d_job *job = v3d_get_job(v3d, nr_cbufs, cbufs, zsbuf);
|
||||
struct v3d_job *job = v3d_get_job(v3d, nr_cbufs, cbufs, zsbuf, NULL);
|
||||
|
||||
if (v3d->framebuffer.samples >= 1)
|
||||
job->msaa = true;
|
||||
|
||||
@@ -114,7 +114,8 @@ static void
|
||||
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)
|
||||
uint32_t *stores_pending, bool general_color_clear,
|
||||
bool is_blit)
|
||||
{
|
||||
struct v3d_surface *surf = v3d_surface(psurf);
|
||||
bool separate_stencil = surf->separate_stencil && buffer == STENCIL;
|
||||
@@ -158,8 +159,11 @@ store_general(struct v3d_job *job,
|
||||
store.height_in_ub_or_stride = slice->stride;
|
||||
}
|
||||
|
||||
assert(!is_blit || 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)
|
||||
store.decimate_mode = V3D_DECIMATE_MODE_4X;
|
||||
else
|
||||
store.decimate_mode = V3D_DECIMATE_MODE_SAMPLE_0;
|
||||
|
||||
@@ -213,6 +217,14 @@ 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.
|
||||
*/
|
||||
assert(!job->bbuf || job->load == 0);
|
||||
|
||||
for (int i = 0; i < job->nr_cbufs; i++) {
|
||||
uint32_t bit = PIPE_CLEAR_COLOR0 << i;
|
||||
@@ -229,6 +241,12 @@ 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))) {
|
||||
@@ -313,6 +331,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);
|
||||
for (int i = 0; i < job->nr_cbufs; i++) {
|
||||
uint32_t bit = PIPE_CLEAR_COLOR0 << i;
|
||||
if (!(job->store & bit))
|
||||
@@ -325,7 +344,7 @@ v3d_rcl_emit_stores(struct v3d_job *job, struct v3d_cl *cl, int layer)
|
||||
}
|
||||
|
||||
store_general(job, cl, psurf, layer, RENDER_TARGET_0 + i, bit,
|
||||
&stores_pending, general_color_clear);
|
||||
&stores_pending, general_color_clear, job->bbuf);
|
||||
}
|
||||
|
||||
if (job->store & PIPE_CLEAR_DEPTHSTENCIL && job->zsbuf &&
|
||||
@@ -336,20 +355,23 @@ v3d_rcl_emit_stores(struct v3d_job *job, struct v3d_cl *cl, int layer)
|
||||
store_general(job, cl, job->zsbuf, layer,
|
||||
Z, PIPE_CLEAR_DEPTH,
|
||||
&stores_pending,
|
||||
general_color_clear);
|
||||
general_color_clear,
|
||||
false);
|
||||
}
|
||||
|
||||
if (job->store & PIPE_CLEAR_STENCIL) {
|
||||
store_general(job, cl, job->zsbuf, layer,
|
||||
STENCIL, PIPE_CLEAR_STENCIL,
|
||||
&stores_pending,
|
||||
general_color_clear);
|
||||
general_color_clear,
|
||||
false);
|
||||
}
|
||||
} else {
|
||||
store_general(job, cl, job->zsbuf, layer,
|
||||
zs_buffer_from_pipe_bits(job->store),
|
||||
job->store & PIPE_CLEAR_DEPTHSTENCIL,
|
||||
&stores_pending, general_color_clear);
|
||||
&stores_pending, general_color_clear,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,6 +495,10 @@ v3d_setup_render_target(struct v3d_job *job, int cbuf,
|
||||
|
||||
struct v3d_surface *surf = v3d_surface(job->cbufs[cbuf]);
|
||||
*rt_bpp = surf->internal_bpp;
|
||||
if (job->bbuf) {
|
||||
struct v3d_surface *bsurf = v3d_surface(job->bbuf);
|
||||
*rt_bpp = MAX2(*rt_bpp, bsurf->internal_bpp);
|
||||
}
|
||||
*rt_type = surf->internal_type;
|
||||
*rt_clamp = V3D_RENDER_TARGET_CLAMP_NONE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user