Module: Mesa Branch: main Commit: 4afcd0c6d6246e21bf9a68a9949355ac68610231 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=4afcd0c6d6246e21bf9a68a9949355ac68610231
Author: Roman Stratiienko <r.stratiie...@gmail.com> Date: Mon Sep 25 21:39:34 2023 +0300 u_gralloc: Add support for gbm_gralloc Although gbm_gralloc has not been maintained for a long time, it is still used in android-x86, BlissOS and WayDroid. Let's add support so that x86 drivers no longer need to request tiling flags from the kernel. Acked-by: Chia-I Wu <olva...@gmail.com> Acked-by: David Heidelberg <david.heidelb...@collabora.com> Tested-by: HMTheBoy154 <buingo...@gmail.com> # BlissOS 15 & Mesa 23.3.2 Tested-by: Mauro Rossi <issor.or...@gmail.com> # android-x86 for mesa 24.0.0-devel on Skylake GT2 Signed-off-by: Roman Stratiienko <r.stratiie...@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25380> --- src/util/u_gralloc/meson.build | 1 + src/util/u_gralloc/u_gralloc.c | 1 + src/util/u_gralloc/u_gralloc.h | 1 + src/util/u_gralloc/u_gralloc_internal.h | 1 + src/util/u_gralloc/u_gralloc_libdrm.c | 106 ++++++++++++++++++++++++++++++++ src/util/u_gralloc/u_gralloc_libdrm.h | 62 +++++++++++++++++++ 6 files changed, 172 insertions(+) diff --git a/src/util/u_gralloc/meson.build b/src/util/u_gralloc/meson.build index 39f181cae3f..913fc7c786d 100644 --- a/src/util/u_gralloc/meson.build +++ b/src/util/u_gralloc/meson.build @@ -12,6 +12,7 @@ files_u_gralloc = files( 'u_gralloc_internal.c', 'u_gralloc_fallback.c', 'u_gralloc_cros_api.c', + 'u_gralloc_libdrm.c', 'u_gralloc_qcom.c', ) diff --git a/src/util/u_gralloc/u_gralloc.c b/src/util/u_gralloc/u_gralloc.c index 1e694e4e66e..b92057c515d 100644 --- a/src/util/u_gralloc/u_gralloc.c +++ b/src/util/u_gralloc/u_gralloc.c @@ -28,6 +28,7 @@ static const struct u_grallocs { #ifdef USE_IMAPPER4_METADATA_API {.type = U_GRALLOC_TYPE_GRALLOC4, .create = u_gralloc_imapper_api_create}, #endif /* USE_IMAPPER4_METADATA_API */ + {.type = U_GRALLOC_TYPE_LIBDRM, .create = u_gralloc_libdrm_create}, {.type = U_GRALLOC_TYPE_QCOM, .create = u_gralloc_qcom_create}, {.type = U_GRALLOC_TYPE_FALLBACK, .create = u_gralloc_fallback_create}, }; diff --git a/src/util/u_gralloc/u_gralloc.h b/src/util/u_gralloc/u_gralloc.h index 9a56093fb41..a04a490d636 100644 --- a/src/util/u_gralloc/u_gralloc.h +++ b/src/util/u_gralloc/u_gralloc.h @@ -51,6 +51,7 @@ enum u_gralloc_type { U_GRALLOC_TYPE_AUTO, U_GRALLOC_TYPE_GRALLOC4, U_GRALLOC_TYPE_CROS, + U_GRALLOC_TYPE_LIBDRM, U_GRALLOC_TYPE_QCOM, U_GRALLOC_TYPE_FALLBACK, U_GRALLOC_TYPE_COUNT, diff --git a/src/util/u_gralloc/u_gralloc_internal.h b/src/util/u_gralloc/u_gralloc_internal.h index b9bceef46cd..80975607f44 100644 --- a/src/util/u_gralloc/u_gralloc_internal.h +++ b/src/util/u_gralloc/u_gralloc_internal.h @@ -36,6 +36,7 @@ extern struct u_gralloc *u_gralloc_cros_api_create(void); extern struct u_gralloc *u_gralloc_imapper_api_create(void); #endif extern struct u_gralloc *u_gralloc_qcom_create(void); +extern struct u_gralloc *u_gralloc_libdrm_create(void); extern struct u_gralloc *u_gralloc_fallback_create(void); /* Helpers for legacy grallocs */ diff --git a/src/util/u_gralloc/u_gralloc_libdrm.c b/src/util/u_gralloc/u_gralloc_libdrm.c new file mode 100644 index 00000000000..01c3c178abb --- /dev/null +++ b/src/util/u_gralloc/u_gralloc_libdrm.c @@ -0,0 +1,106 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2023 Roman Stratiienko (r.stratiie...@gmail.com) + * SPDX-License-Identifier: MIT + */ + +#include "u_gralloc_libdrm.h" + +#include <assert.h> +#include <dlfcn.h> +#include <errno.h> +#include <string.h> +#include <hardware/gralloc.h> + +#include "util/log.h" +#include "util/u_memory.h" + +#include "u_gralloc_internal.h" + +/* Despite minigbm becoming standard gralloc for many distributions, some + * users still rely on legacy grallocs, like gbm_gralloc that use a native + * handle header that is located at libdrm/android/gralloc_handle.h. + * Using this gralloc is not recommended for new distributions. + */ + +struct libdrm_gralloc { + struct u_gralloc base; + gralloc_module_t *gralloc_module; + struct u_gralloc *fallback_gralloc; +}; + +static const char gbm_gralloc_module_name[] = "GBM Memory Allocator"; + +static int +get_buffer_info(struct u_gralloc *gralloc, + struct u_gralloc_buffer_handle *hnd, + struct u_gralloc_buffer_basic_info *out) +{ + struct libdrm_gralloc *gr = (struct libdrm_gralloc *)gralloc; + struct gralloc_handle_t *handle = (struct gralloc_handle_t *)hnd->handle; + assert(handle->base.numFds == GRALLOC_HANDLE_NUM_FDS); + assert(handle->base.numInts == GRALLOC_HANDLE_NUM_INTS); + assert(handle->magic == GRALLOC_HANDLE_MAGIC); + + if (handle->version != GRALLOC_HANDLE_VERSION) + mesa_loge("Unexpected gralloc handle version %d", handle->version); + + assert(handle->version == GRALLOC_HANDLE_VERSION); + + /* Query basic information using fallback gralloc */ + u_gralloc_get_buffer_basic_info(gr->fallback_gralloc, hnd, out); + + /* Fill the known data using libdrm gralloc handle */ + out->modifier = handle->modifier; + out->strides[0] = handle->stride; + + return 0; +} + +static int +destroy(struct u_gralloc *gralloc) +{ + struct libdrm_gralloc *gr = (struct libdrm_gralloc *)gralloc; + if (gr->gralloc_module) + dlclose(gr->gralloc_module->common.dso); + + if (gr->fallback_gralloc) + gr->fallback_gralloc->ops.destroy(gr->fallback_gralloc); + + FREE(gr); + + return 0; +} + +struct u_gralloc * +u_gralloc_libdrm_create() +{ + struct libdrm_gralloc *gr = CALLOC_STRUCT(libdrm_gralloc); + int err = 0; + + err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, + (const hw_module_t **)&gr->gralloc_module); + + if (err) + goto fail; + + if (strcmp(gr->gralloc_module->common.name, gbm_gralloc_module_name) != 0) + goto fail; + + gr->base.ops.get_buffer_basic_info = get_buffer_info; + gr->base.ops.destroy = destroy; + + mesa_logw("Using gralloc header from libdrm/android/gralloc_handle.h. " + " This is not recommended for new distributions. " + " Initializing a fallback gralloc as a helper:"); + + gr->fallback_gralloc = u_gralloc_fallback_create(); + + return &gr->base; + +fail: + destroy(&gr->base); + + return NULL; +} diff --git a/src/util/u_gralloc/u_gralloc_libdrm.h b/src/util/u_gralloc/u_gralloc_libdrm.h new file mode 100644 index 00000000000..e3e2be85a47 --- /dev/null +++ b/src/util/u_gralloc/u_gralloc_libdrm.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2010-2011 Chia-I Wu <olva...@gmail.com> + * Copyright (C) 2010-2011 LunarG Inc. + * Copyright (C) 2016 Linaro, Ltd., Rob Herring <r...@kernel.org> + * Copyright (C) 2018 Collabora, Robert Foss <robert.f...@collabora.com> + * + * SPDX-License-Identifier: MIT + * + * Copied from: + * https://gitlab.freedesktop.org/mesa/drm/-/blob/6abc164052e4902f67213baa279d743cf46227d4/android/gralloc_handle.h + */ + +#ifndef __ANDROID_GRALLOC_HANDLE_H__ +#define __ANDROID_GRALLOC_HANDLE_H__ + +#include <cutils/native_handle.h> +#include <stdint.h> + +struct gralloc_handle_t { + native_handle_t base; + + /* dma-buf file descriptor + * Must be located first since, native_handle_t is allocated + * using native_handle_create(), which allocates space for + * sizeof(native_handle_t) + sizeof(int) * (numFds + numInts) + * numFds = GRALLOC_HANDLE_NUM_FDS + * numInts = GRALLOC_HANDLE_NUM_INTS + * Where numFds represents the number of FDs and + * numInts represents the space needed for the + * remainder of this struct. + * And the FDs are expected to be found first following + * native_handle_t. + */ + int prime_fd; + + /* api variables */ + uint32_t magic; /* differentiate between allocator impls */ + uint32_t version; /* api version */ + + uint32_t width; /* width of buffer in pixels */ + uint32_t height; /* height of buffer in pixels */ + uint32_t format; /* pixel format (Android) */ + uint32_t usage; /* android libhardware usage flags */ + + uint32_t stride; /* the stride in bytes */ + int data_owner; /* owner of data (for validation) */ + uint64_t modifier __attribute__((aligned(8))); /* buffer modifiers */ + + union { + void *data; /* pointer to struct gralloc_gbm_bo_t */ + uint64_t reserved; + } __attribute__((aligned(8))); +}; + +#define GRALLOC_HANDLE_VERSION 4 +#define GRALLOC_HANDLE_MAGIC 0x60585350 +#define GRALLOC_HANDLE_NUM_FDS 1 +#define GRALLOC_HANDLE_NUM_INTS ( \ + ((sizeof(struct gralloc_handle_t) - sizeof(native_handle_t))/sizeof(int)) \ + - GRALLOC_HANDLE_NUM_FDS) + +#endif /* __ANDROID_GRALLOC_HANDLE_H__ */