asahi: shrink VA space for sparse emulation

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34486>
This commit is contained in:
Alyssa Rosenzweig 2025-04-11 11:57:44 -04:00 committed by Marge Bot
parent 1f718c5b0f
commit c2d00c94b1
2 changed files with 32 additions and 0 deletions

View file

@ -9,6 +9,7 @@
#include <inttypes.h>
#include "clc/asahi_clc.h"
#include "drm-uapi/asahi_drm.h"
#include "util/bitscan.h"
#include "util/macros.h"
#include "util/ralloc.h"
#include "util/timespec.h"
@ -33,6 +34,7 @@
#include "util/os_mman.h"
#include "util/os_time.h"
#include "util/simple_mtx.h"
#include "util/u_math.h"
#include "util/u_printf.h"
#include "git_sha1.h"
#include "nir_serialize.h"
@ -614,6 +616,23 @@ agx_open_device(void *memctx, struct agx_device *dev)
return false;
}
/* Round the user VA window to powers-of-two... */
user_start = util_next_power_of_two64(user_start);
user_size = util_next_power_of_two64(user_size + 1) >> 1;
/* ...so when we cut user size in half to emulate sparse buffers... */
user_size /= 2;
/* ...or maybe in quarters if necessary to disambiguate */
if (user_size == user_start) {
user_size /= 2;
}
/* ...we can distinguish the top/bottom half by an address bit */
dev->sparse_ro_offset = user_size;
assert((user_start & dev->sparse_ro_offset) == 0);
assert(((user_start + (user_size - 1)) & dev->sparse_ro_offset) == 0);
simple_mtx_init(&dev->vma_lock, mtx_plain);
util_vma_heap_init(&dev->main_heap, user_start, user_size);
util_vma_heap_init(&dev->usc_heap, dev->shader_base, shader_size);

View file

@ -120,6 +120,19 @@ struct agx_device {
struct util_vma_heap usc_heap;
uint64_t guard_size;
/* To emulate sparse-resident buffers, we map buffers in both the bottom half
* and top half of the address space. sparse_ro_offset controls the
* partitioning. This is a power-of-two that &'s zero in bottom (read-write)
* buffers but non-zero in top (read-only) shadow mappings.
*
* In other words, given an address X, we can check if it is in the top half
* if (X & sparse_ro_offset) != 0.
*
* Given a bottom half address X, we can get the top half address
* equivalently as (X + sparse_ro_offset) or (X | sparse_ro_offset).
*/
uint64_t sparse_ro_offset;
struct renderonly *ro;
pthread_mutex_t bo_map_lock;