diff options
author | Łukasz Stelmach <l.stelmach@samsung.com> | 2023-10-19 16:21:02 +0200 |
---|---|---|
committer | Łukasz Stelmach <l.stelmach@samsung.com> | 2023-11-24 13:35:08 +0100 |
commit | 280ced031cea116524cc90319d1dca04e5281d60 (patch) | |
tree | 1e3b45ba34bad055be751a540a59964d989cd172 | |
parent | fbb83db100690fe9d69402a4626aca0c991f6eec (diff) | |
download | libtbm-dumb-sandbox/lstelmach/virgl.tar.gz libtbm-dumb-sandbox/lstelmach/virgl.tar.bz2 libtbm-dumb-sandbox/lstelmach/virgl.zip |
Fix for virglrenderersandbox/lstelmach/virgl
virglrenderer used by QEMU together with virtio-gpu allows allocations
that are at most 16384 pixels wide or high. This means it can provide
buffers as large as 256 MiB but they need to be 16k by 16k pixels and
not 256M by 1. Square root approximation is quick and although it results
in buffers being allocated slightly larger than requested, but the error
isn't significant.
Change-Id: Ife231fd5ac4eae0181680e86ec9c239920cdef41
Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
-rw-r--r-- | src/tbm_backend_dumb.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/src/tbm_backend_dumb.c b/src/tbm_backend_dumb.c index 5963f49..0edb5dc 100644 --- a/src/tbm_backend_dumb.c +++ b/src/tbm_backend_dumb.c @@ -640,6 +640,24 @@ tbm_dumb_bufmgr_get_plane_data(hal_tbm_bufmgr *bufmgr, return HAL_TBM_ERROR_NONE; } +#define LOG2(x) ((unsigned int)(sizeof(unsigned int) * 8 - 1 - __builtin_clz(x))) + +static inline unsigned int dirty_sqrt(unsigned int v) +{ + unsigned int log2 = LOG2(v); + + if (log2 < 0) + return 0; + + if (log2 == 0) + return 1; + + log2 += !!(v & (1 << (log2 - 1))); + log2 >>= 1; + + return 1 << log2; +} + static hal_tbm_bo * tbm_dumb_bufmgr_alloc_bo(hal_tbm_bufmgr *bufmgr, unsigned int size, hal_tbm_bo_memory_type flags, hal_tbm_error *error) @@ -662,9 +680,18 @@ tbm_dumb_bufmgr_alloc_bo(hal_tbm_bufmgr *bufmgr, unsigned int size, //as we know only size for new bo set height=1 and bpp=8 and in this case //width will by equal to size in bytes; - create_dumb_arg.height = 1; create_dumb_arg.bpp = 32; // virtio-gpu refuses to accept bpp=8 - create_dumb_arg.width = (size + 4 - 1) / 4; + if (size <= 16384) { + create_dumb_arg.height = 1; + create_dumb_arg.width = (size + 4 - 1) / 4; + } else { + unsigned int words = (size + 4 - 1) / 4; + unsigned int root = dirty_sqrt(words); + + create_dumb_arg.height = root; + create_dumb_arg.width = (words + root - 1) / root; + } + create_dumb_arg.flags = dumb_flags; if (drmIoctl(bufmgr_data->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb_arg)) { TBM_BACKEND_ERR("fail to DRM_IOCTL_MODE_CREATE_DUMB flag:%x size:%d", |