summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commit280ced031cea116524cc90319d1dca04e5281d60 (patch)
tree1e3b45ba34bad055be751a540a59964d989cd172
parentfbb83db100690fe9d69402a4626aca0c991f6eec (diff)
downloadlibtbm-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.c31
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",