v3d: use heuristic to enable double-buffer mode

This is still experimental and only enabled if V3D_DEBUG=db
is set.

Reviewed-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32111>
This commit is contained in:
Iago Toral Quiroga 2024-10-29 11:53:49 +01:00 committed by Marge Bot
parent d81bcbe3de
commit 6d54a5514c
4 changed files with 49 additions and 6 deletions

View File

@ -530,6 +530,7 @@ v3d_tlb_blit(struct pipe_context *pctx, struct pipe_blit_info *info)
src_surf);
job->msaa = msaa;
job->double_buffer = double_buffer;
job->can_use_double_buffer = !job->msaa && V3D_DBG(DOUBLE_BUFFER);
job->internal_bpp = max_bpp;
job->draw_min_x = info->dst.box.x;
job->draw_min_y = info->dst.box.y;

View File

@ -40,6 +40,7 @@
#include "drm-uapi/v3d_drm.h"
#include "v3d_screen.h"
#include "broadcom/common/v3d_limits.h"
#include "broadcom/common/v3d_util.h"
#include "broadcom/simulator/v3d_simulator.h"
#include "broadcom/compiler/v3d_compiler.h"
@ -474,9 +475,17 @@ struct v3d_job {
float clear_z;
uint8_t clear_s;
/* If we found anything in the job that is not compatible with
* double-buffer mode
*/
bool can_use_double_buffer;
/* If TLB double-buffering is enabled for this job */
bool double_buffer;
/* Tracks score for double-buffer mode heuristic */
struct v3d_double_buffer_score double_buffer_score;
/**
* Set if some drawing (triangles, blits, or just a glClear()) has
* been done to the FBO, meaning that we need to

View File

@ -376,7 +376,12 @@ v3d_get_job(struct v3d_context *v3d,
}
}
job->double_buffer = false;
/* By default we disable double buffer but we allow it to be enabled
* later on (except for msaa) if we don't find any other reason
* to disable it.
*/
job->can_use_double_buffer = !job->msaa && V3D_DBG(DOUBLE_BUFFER);
job->double_buffer = false;
memcpy(&job->key, &local_key, sizeof(local_key));
_mesa_hash_table_insert(v3d->jobs, &job->key, job);
@ -546,13 +551,14 @@ alloc_tile_state(struct v3d_job *job)
static void
enable_double_buffer_mode(struct v3d_job *job)
{
/* For now we only allow double-buffer mode through envvar */
if (!V3D_DBG(DOUBLE_BUFFER))
/* Don't enable if we have seen incompatibilities */
if (!job->can_use_double_buffer)
return;
/* MSAA is not compatible with double buffering */
if (job->msaa)
return;
/* For now we only allow double buffer via envvar and only for jobs
* that are not MSAA, which is incompatible.
*/
assert(V3D_DBG(DOUBLE_BUFFER) && !job->msaa);
/* Tile loads are serialized against stores, in which case we don't get
* any benefits from enabling double-buffer and would just pay the price
@ -567,6 +573,9 @@ enable_double_buffer_mode(struct v3d_job *job)
if (!job->store)
return;
if (!v3d_double_buffer_score_ok(&job->double_buffer_score))
return;
/* Enable double-buffer mode.
*
* This will reduce the tile size so we need to recompute state

View File

@ -1034,6 +1034,25 @@ v3d_check_compiled_shaders(struct v3d_context *v3d)
return false;
}
static void
update_double_buffer_score(struct v3d_job *job, uint32_t vertex_count)
{
if (!job->can_use_double_buffer)
return;
if (job->v3d->prog.gs) {
job->can_use_double_buffer = false;
return;
}
struct v3d_compiled_shader *vs = job->v3d->prog.vs;
struct v3d_compiled_shader *fs = job->v3d->prog.fs;
v3d_update_double_buffer_score(vertex_count,
vs->qpu_size, fs->qpu_size,
vs->prog_data.base, fs->prog_data.base,
&job->double_buffer_score);
}
static void
v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
unsigned drawid_offset,
@ -1388,6 +1407,11 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
v3d_job_add_bo(job, rsc->bo);
}
if (indirect && indirect->buffer)
job->can_use_double_buffer = false;
else
update_double_buffer_score(job, draws[0].count * info->instance_count);
if (job->referenced_size > 768 * 1024 * 1024) {
perf_debug("Flushing job with %dkb to try to free up memory\n",
job->referenced_size / 1024);