From db8ab5244770a1ccd4ba06ca7ef00c5175eb1f9d Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 9 Jun 2022 08:50:44 -0400 Subject: [PATCH] gallium: Stub support for Asahi + DRM Copy-paste a pile of winsys code from panfrost and find-and-replace the name to asahi. This should contain all the glue code needed for asahi+kmsro. The kernel driver is under way (led by Asahi Lina, not me), but it's not wred up here. My goal was rather to run shader-db, which expects a render node, which means drm-shim, which means DRM loader support. With this patch and a trivial drm-shim, shader-db runs. In general I am reticent to touch UABI related code when the UABI hasn't been finalized upstream, or started design at all, hence the RFC. Realistically this patch assumes the following about the future UABI: 0. It will be a DRM driver. This is nonnegotiable. 1. The render node will be named "asahi". The other reasonable name would be "apple", which I'm using for the display controller (not yet upstream, but getting close). 2. Display and rendering will be split in the kernel, requiring kmsro in userspace, as agreed in past discussions. The 3D accelerator (AGX) and the display controller (DCP) are completely orthogonal blocks with separate lineages. True, Apple A14 (~= M1) has AGX and DCP together, and it seems like all the chips that will get upstream support will have this for the forseeable future. Nevertheless, it's a historical coincidence. Apple A12 had an AGX block with a pre-DCP Apple display controller, which would use a completely different display driver. Older SoCs had a PowerVR block with an Apple shader core, with a pre-DCP Apple display controller. Even older SoCs had a pure PowerVR block (+ Apple display). The AGX and DCP kernel drivers are not expected to share any nontrivial code. We don't gain anything by bundling them together. Likewise, the many codec blocks are completely orthogonal. This is all standard practice for Arm SoCs. It is true that AGX has never been used with a non-Apple display controller; it is highly unlikely this would change (either by AGX licensing out or something like Mali-DP getting licensed in). But an extra kmsro user doesn't actually add more complexity to Mesa, so shrug. Signed-off-by: Alyssa Rosenzweig Reviewed-by: Eric Engestrom [meson, ack on gallium] Part-of: --- meson.build | 6 ++- .../auxiliary/pipe-loader/pipe_loader_drm.c | 1 + .../auxiliary/target-helpers/drm_helper.h | 18 +++++++ .../target-helpers/drm_helper_public.h | 1 + .../target-helpers/inline_sw_helper.h | 2 +- .../auxiliary/target-helpers/sw_helper.h | 2 +- src/gallium/drivers/asahi/agx_pipe.c | 2 +- src/gallium/drivers/asahi/agx_public.h | 5 +- src/gallium/drivers/asahi/meson.build | 2 +- src/gallium/meson.build | 1 + src/gallium/targets/dri/target.c | 4 ++ src/gallium/targets/pipe-loader/meson.build | 2 +- .../winsys/asahi/drm/asahi_drm_public.h | 36 ++++++++++++++ .../winsys/asahi/drm/asahi_drm_winsys.c | 49 +++++++++++++++++++ src/gallium/winsys/asahi/drm/meson.build | 30 ++++++++++++ .../winsys/kmsro/drm/kmsro_drm_winsys.c | 14 ++++++ src/gallium/winsys/kmsro/drm/meson.build | 3 ++ 17 files changed, 171 insertions(+), 7 deletions(-) create mode 100644 src/gallium/winsys/asahi/drm/asahi_drm_public.h create mode 100644 src/gallium/winsys/asahi/drm/asahi_drm_winsys.c create mode 100644 src/gallium/winsys/asahi/drm/meson.build diff --git a/meson.build b/meson.build index f70188fc7b3..7f86a0ec985 100644 --- a/meson.build +++ b/meson.build @@ -234,7 +234,11 @@ foreach gallium_driver : gallium_drivers endforeach with_gallium = gallium_drivers.length() != 0 -with_gallium_kmsro = with_gallium_v3d or with_gallium_vc4 or with_gallium_etnaviv or with_gallium_panfrost or with_gallium_lima or with_gallium_freedreno +with_gallium_kmsro = with_gallium_v3d or with_gallium_vc4 or with_gallium_etnaviv or with_gallium_panfrost or with_gallium_lima or with_gallium_freedreno or with_gallium_asahi + +if not system_has_kms_drm + with_gallium_kmsro = false +endif with_dri = false if with_gallium and system_has_kms_drm diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c b/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c index b3bdfc90d97..b27858ab467 100644 --- a/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c +++ b/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c @@ -82,6 +82,7 @@ static const struct drm_driver_descriptor *driver_descriptors[] = { &v3d_driver_descriptor, &vc4_driver_descriptor, &panfrost_driver_descriptor, + &asahi_driver_descriptor, &etnaviv_driver_descriptor, &tegra_driver_descriptor, &lima_driver_descriptor, diff --git a/src/gallium/auxiliary/target-helpers/drm_helper.h b/src/gallium/auxiliary/target-helpers/drm_helper.h index 81f7fc33bf1..7dff0b66c18 100644 --- a/src/gallium/auxiliary/target-helpers/drm_helper.h +++ b/src/gallium/auxiliary/target-helpers/drm_helper.h @@ -67,6 +67,7 @@ const struct drm_driver_descriptor descriptor_name = { \ #undef GALLIUM_ETNAVIV #undef GALLIUM_PANFROST #undef GALLIUM_LIMA +#undef GALLIUM_ASAHI #endif #ifdef GALLIUM_I915 @@ -355,6 +356,23 @@ DRM_DRIVER_DESCRIPTOR(panfrost, NULL, 0) DRM_DRIVER_DESCRIPTOR_STUB(panfrost) #endif +#ifdef GALLIUM_ASAHI +#include "asahi/drm/asahi_drm_public.h" + +static struct pipe_screen * +pipe_asahi_create_screen(int fd, const struct pipe_screen_config *config) +{ + struct pipe_screen *screen; + + screen = asahi_drm_screen_create(fd); + return screen ? debug_screen_wrap(screen) : NULL; +} +DRM_DRIVER_DESCRIPTOR(asahi, NULL, 0) + +#else +DRM_DRIVER_DESCRIPTOR_STUB(asahi) +#endif + #ifdef GALLIUM_ETNAVIV #include "etnaviv/drm/etnaviv_drm_public.h" diff --git a/src/gallium/auxiliary/target-helpers/drm_helper_public.h b/src/gallium/auxiliary/target-helpers/drm_helper_public.h index 478e72b8525..89c0a429967 100644 --- a/src/gallium/auxiliary/target-helpers/drm_helper_public.h +++ b/src/gallium/auxiliary/target-helpers/drm_helper_public.h @@ -18,6 +18,7 @@ extern const struct drm_driver_descriptor virtio_gpu_driver_descriptor; extern const struct drm_driver_descriptor v3d_driver_descriptor; extern const struct drm_driver_descriptor vc4_driver_descriptor; extern const struct drm_driver_descriptor panfrost_driver_descriptor; +extern const struct drm_driver_descriptor asahi_driver_descriptor; extern const struct drm_driver_descriptor etnaviv_driver_descriptor; extern const struct drm_driver_descriptor tegra_driver_descriptor; extern const struct drm_driver_descriptor lima_driver_descriptor; diff --git a/src/gallium/auxiliary/target-helpers/inline_sw_helper.h b/src/gallium/auxiliary/target-helpers/inline_sw_helper.h index 20cb933fb70..91056dc7bae 100644 --- a/src/gallium/auxiliary/target-helpers/inline_sw_helper.h +++ b/src/gallium/auxiliary/target-helpers/inline_sw_helper.h @@ -69,7 +69,7 @@ sw_screen_create_named(struct sw_winsys *winsys, const char *driver) #if defined(GALLIUM_ASAHI) if (screen == NULL && strcmp(driver, "asahi") == 0) - screen = agx_screen_create(winsys); + screen = agx_screen_create(0, NULL, winsys); #endif return screen ? debug_screen_wrap(screen) : NULL; diff --git a/src/gallium/auxiliary/target-helpers/sw_helper.h b/src/gallium/auxiliary/target-helpers/sw_helper.h index dcf3a60a913..29d65aecbea 100644 --- a/src/gallium/auxiliary/target-helpers/sw_helper.h +++ b/src/gallium/auxiliary/target-helpers/sw_helper.h @@ -73,7 +73,7 @@ sw_screen_create_named(struct sw_winsys *winsys, const struct pipe_screen_config #if defined(GALLIUM_ASAHI) if (screen == NULL && strcmp(driver, "asahi") == 0) - screen = agx_screen_create(winsys); + screen = agx_screen_create(0, NULL, winsys); #endif return screen; diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 149597903c2..409164fefe2 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -1155,7 +1155,7 @@ static const struct u_transfer_vtbl transfer_vtbl = { }; struct pipe_screen * -agx_screen_create(struct sw_winsys *winsys) +agx_screen_create(int fd, struct renderonly *ro, struct sw_winsys *winsys) { struct agx_screen *agx_screen; struct pipe_screen *screen; diff --git a/src/gallium/drivers/asahi/agx_public.h b/src/gallium/drivers/asahi/agx_public.h index 4bf706286bd..5cc5c325401 100644 --- a/src/gallium/drivers/asahi/agx_public.h +++ b/src/gallium/drivers/asahi/agx_public.h @@ -29,7 +29,10 @@ extern "C" { struct pipe_screen; struct sw_winsys; -struct pipe_screen *agx_screen_create(struct sw_winsys *winsys); +struct renderonly; + +struct pipe_screen * +agx_screen_create(int fd, struct renderonly *ro, struct sw_winsys *winsys); #ifdef __cplusplus } diff --git a/src/gallium/drivers/asahi/meson.build b/src/gallium/drivers/asahi/meson.build index c19ae0f20bf..0e7bad9bede 100644 --- a/src/gallium/drivers/asahi/meson.build +++ b/src/gallium/drivers/asahi/meson.build @@ -37,5 +37,5 @@ libasahi = static_library( driver_asahi = declare_dependency( compile_args : '-DGALLIUM_ASAHI', - link_with : [libasahi, libasahi_compiler, libasahi_lib, libasahi_layout, libasahi_decode] + link_with : [libasahi, libasahiwinsys, libasahi_compiler, libasahi_lib, libasahi_layout, libasahi_decode] ) diff --git a/src/gallium/meson.build b/src/gallium/meson.build index 4d275759215..148c7220382 100644 --- a/src/gallium/meson.build +++ b/src/gallium/meson.build @@ -54,6 +54,7 @@ else driver_swrast = declare_dependency() endif if with_gallium_asahi + subdir('winsys/asahi/drm') subdir('drivers/asahi') else driver_asahi = declare_dependency() diff --git a/src/gallium/targets/dri/target.c b/src/gallium/targets/dri/target.c index ede23d3f47f..d506869cbb4 100644 --- a/src/gallium/targets/dri/target.c +++ b/src/gallium/targets/dri/target.c @@ -84,6 +84,10 @@ DEFINE_LOADER_DRM_ENTRYPOINT(vc4) DEFINE_LOADER_DRM_ENTRYPOINT(panfrost) #endif +#if defined(GALLIUM_ASAHI) +DEFINE_LOADER_DRM_ENTRYPOINT(asahi) +#endif + #if defined(GALLIUM_ETNAVIV) DEFINE_LOADER_DRM_ENTRYPOINT(etnaviv) #endif diff --git a/src/gallium/targets/pipe-loader/meson.build b/src/gallium/targets/pipe-loader/meson.build index c9c995113c4..aff9f932055 100644 --- a/src/gallium/targets/pipe-loader/meson.build +++ b/src/gallium/targets/pipe-loader/meson.build @@ -48,7 +48,7 @@ pipe_loader_install_dir = join_paths(get_option('libdir'), 'gallium-pipe') _kmsro_targets = [ driver_kmsro, driver_v3d, driver_vc4, driver_freedreno, driver_etnaviv, - driver_panfrost, driver_lima, + driver_panfrost, driver_lima, driver_asahi, ] if with_gallium_v3d diff --git a/src/gallium/winsys/asahi/drm/asahi_drm_public.h b/src/gallium/winsys/asahi/drm/asahi_drm_public.h new file mode 100644 index 00000000000..cdc800133b7 --- /dev/null +++ b/src/gallium/winsys/asahi/drm/asahi_drm_public.h @@ -0,0 +1,36 @@ +/* + * Copyright © 2014 Broadcom + * Copyright © 208 Alyssa Rosenzweig + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef __ASAHI_DRM_PUBLIC_H__ +#define __ASAHI_DRM_PUBLIC_H__ + +#include + +struct pipe_screen; +struct renderonly; + +struct pipe_screen *asahi_drm_screen_create(int drmFD); +struct pipe_screen *asahi_drm_screen_create_renderonly(struct renderonly *ro); + +#endif /* __ASAHI_DRM_PUBLIC_H__ */ diff --git a/src/gallium/winsys/asahi/drm/asahi_drm_winsys.c b/src/gallium/winsys/asahi/drm/asahi_drm_winsys.c new file mode 100644 index 00000000000..97273507c5c --- /dev/null +++ b/src/gallium/winsys/asahi/drm/asahi_drm_winsys.c @@ -0,0 +1,49 @@ +/* + * Copyright © 2014 Broadcom + * Copyright © 208 Alyssa Rosenzweig + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "util/format/u_format.h" +#include "util/os_file.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "drm-uapi/drm.h" +#include "renderonly/renderonly.h" +#include "asahi_drm_public.h" +#include "asahi/agx_public.h" + +struct pipe_screen * +asahi_drm_screen_create(int fd) +{ + return agx_screen_create(os_dupfd_cloexec(fd), NULL, NULL); +} + +struct pipe_screen * +asahi_drm_screen_create_renderonly(struct renderonly *ro) +{ + return agx_screen_create(os_dupfd_cloexec(ro->gpu_fd), ro, NULL); +} diff --git a/src/gallium/winsys/asahi/drm/meson.build b/src/gallium/winsys/asahi/drm/meson.build new file mode 100644 index 00000000000..225ed799392 --- /dev/null +++ b/src/gallium/winsys/asahi/drm/meson.build @@ -0,0 +1,30 @@ +# Copyright © 2017 Broadcom +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +libasahiwinsys = static_library( + 'asahiwinsys', + files('asahi_drm_winsys.c'), + include_directories : [ + inc_src, inc_include, + inc_gallium, inc_gallium_aux, inc_gallium_drivers, + ], + gnu_symbol_visibility : 'hidden', + dependencies: dep_libdrm, +) diff --git a/src/gallium/winsys/kmsro/drm/kmsro_drm_winsys.c b/src/gallium/winsys/kmsro/drm/kmsro_drm_winsys.c index 6d2f0cabd67..3c8a3c4519f 100644 --- a/src/gallium/winsys/kmsro/drm/kmsro_drm_winsys.c +++ b/src/gallium/winsys/kmsro/drm/kmsro_drm_winsys.c @@ -32,6 +32,7 @@ #include "freedreno/drm/freedreno_drm_public.h" #include "panfrost/drm/panfrost_drm_public.h" #include "lima/drm/lima_drm_public.h" +#include "asahi/drm/asahi_drm_public.h" #include "xf86drm.h" #include "pipe/p_screen.h" @@ -136,6 +137,19 @@ struct pipe_screen *kmsro_drm_screen_create(int fd, } #endif +#if defined(GALLIUM_ASAHI) + ro->gpu_fd = drmOpenWithType("asahi", NULL, DRM_NODE_RENDER); + + if (ro->gpu_fd >= 0) { + ro->create_for_resource = renderonly_create_kms_dumb_buffer_for_resource; + screen = asahi_drm_screen_create_renderonly(ro); + if (!screen) + goto out_free; + + return screen; + } +#endif + return screen; out_free: diff --git a/src/gallium/winsys/kmsro/drm/meson.build b/src/gallium/winsys/kmsro/drm/meson.build index cec92b1fa15..9b47841407a 100644 --- a/src/gallium/winsys/kmsro/drm/meson.build +++ b/src/gallium/winsys/kmsro/drm/meson.build @@ -37,6 +37,9 @@ endif if with_gallium_panfrost kmsro_c_args += '-DGALLIUM_PANFROST' endif +if with_gallium_asahi + kmsro_c_args += '-DGALLIUM_ASAHI' +endif libkmsrowinsys = static_library( 'kmsrowinsys',