From: Thomas Zimmermann <tzimmermann@suse.de>
To: kraxel@redhat.com, daniel@ffwll.ch, airlied@gmail.com,
mripard@kernel.org, maarten.lankhorst@linux.intel.com
Cc: dri-devel@lists.freedesktop.org, virtualization@lists.linux.dev,
Thomas Zimmermann <tzimmermann@suse.de>
Subject: [PATCH 08/10] drm/bochs: Use GEM SHMEM helpers for memory management
Date: Fri, 23 Aug 2024 14:28:51 +0200 [thread overview]
Message-ID: <20240823124422.286989-9-tzimmermann@suse.de> (raw)
In-Reply-To: <20240823124422.286989-1-tzimmermann@suse.de>
Replace GEM VRAM with GEM SHMEM in bochs. The new memory manager
stores buffer objects in system memory. Makes the driver's memory
management more reliably.
Most of the changes are hidden in external helpers that allocate
buffers. Replacing DRM_GEM_VRAM_DRIVER with DRM_GEM_SHMEM_DRIVER_OPS
swaps these. With GEM VRAM, the video memory was updated directly by
the DRM client. The biggest change within bochs is in atomic_update,
which now updates video memory via memcpy() from the BO in system
memory. Shadow-plane helpers maintaining the pointers to the buffer's
data, so bochs doesn't have to. The update is triggered by each page
flip's call to the framebuffer's dirty helper. The driver supports
damage clipping to minimize memcpy() overhead.
The advantage of GEM SHMEM is that it makes memory management
more reliable. Given DRM's double buffering during page flips, the
minimum amount of video memory is three times the maximum consumption
in some pathological cases. For example, if the maximum size of a GEM
buffer is 1920x1080-32 (i.e., 32-bit FullHD), the buffer size is
8 MiB. Display hardware has to provide at lease 24 MiB to reliably
page flip such configurations. This cannot always be guaranteed and
bochs already contains code to rule out <4 MiB configurations. With
GEM SHMEM, only 8 MiB of video memory are required for the given
example. Unsupported modes can be sorted out easily.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/tiny/Kconfig | 4 +-
drivers/gpu/drm/tiny/bochs.c | 78 +++++++++++++++++-------------------
2 files changed, 38 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig
index f6889f649bc1..8f206c6387ec 100644
--- a/drivers/gpu/drm/tiny/Kconfig
+++ b/drivers/gpu/drm/tiny/Kconfig
@@ -13,10 +13,8 @@ config DRM_ARCPGU
config DRM_BOCHS
tristate "DRM Support for bochs dispi vga interface (qemu stdvga)"
depends on DRM && PCI && MMU
+ select DRM_GEM_SHMEM_HELPER
select DRM_KMS_HELPER
- select DRM_VRAM_HELPER
- select DRM_TTM
- select DRM_TTM_HELPER
help
This is a KMS driver for qemu's stdvga output. Choose this option
for qemu.
diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
index 76e29950a807..bde70a6075ec 100644
--- a/drivers/gpu/drm/tiny/bochs.c
+++ b/drivers/gpu/drm/tiny/bochs.c
@@ -6,13 +6,15 @@
#include <drm/drm_aperture.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_damage_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_edid.h>
-#include <drm/drm_fbdev_ttm.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
-#include <drm/drm_gem_vram_helper.h>
+#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_managed.h>
#include <drm/drm_module.h>
#include <drm/drm_plane_helper.h>
@@ -427,49 +429,49 @@ static int bochs_primary_plane_helper_atomic_check(struct drm_plane *plane,
return 0;
}
-static void bochs_plane_update(struct bochs_device *bochs, struct drm_plane_state *state)
+static void bochs_primary_plane_helper_atomic_update(struct drm_plane *plane,
+ struct drm_atomic_state *state)
{
- struct drm_gem_vram_object *gbo;
- s64 gpu_addr;
-
- if (!state->fb || !bochs->stride)
+ struct drm_device *dev = plane->dev;
+ struct bochs_device *bochs = to_bochs_device(dev);
+ struct drm_plane_state *plane_state = plane->state;
+ struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
+ struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
+ struct drm_framebuffer *fb = plane_state->fb;
+ struct drm_atomic_helper_damage_iter iter;
+ struct drm_rect damage;
+
+ if (!fb || !bochs->stride)
return;
- gbo = drm_gem_vram_of_gem(state->fb->obj[0]);
- gpu_addr = drm_gem_vram_offset(gbo);
- if (WARN_ON_ONCE(gpu_addr < 0))
- return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */
+ drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
+ drm_atomic_for_each_plane_damage(&iter, &damage) {
+ struct iosys_map dst = IOSYS_MAP_INIT_VADDR_IOMEM(bochs->fb_map);
- bochs_hw_setbase(bochs,
- state->crtc_x,
- state->crtc_y,
- state->fb->pitches[0],
- state->fb->offsets[0] + gpu_addr);
- bochs_hw_setformat(bochs, state->fb->format);
-}
-
-static void bochs_primary_plane_helper_atomic_update(struct drm_plane *plane,
- struct drm_atomic_state *state)
-{
- struct bochs_device *bochs = to_bochs_device(plane->dev);
- struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
+ iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, &damage));
+ drm_fb_memcpy(&dst, fb->pitches, shadow_plane_state->data, fb, &damage);
+ }
- bochs_plane_update(bochs, plane_state);
+ /* Always scanout image at VRAM offset 0 */
+ bochs_hw_setbase(bochs,
+ plane_state->crtc_x,
+ plane_state->crtc_y,
+ fb->pitches[0],
+ 0);
+ bochs_hw_setformat(bochs, fb->format);
}
static const struct drm_plane_helper_funcs bochs_primary_plane_helper_funcs = {
- DRM_GEM_VRAM_PLANE_HELPER_FUNCS,
+ DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
.atomic_check = bochs_primary_plane_helper_atomic_check,
.atomic_update = bochs_primary_plane_helper_atomic_update,
};
static const struct drm_plane_funcs bochs_primary_plane_funcs = {
- .update_plane = drm_atomic_helper_update_plane,
- .disable_plane = drm_atomic_helper_disable_plane,
- .destroy = drm_plane_cleanup,
- .reset = drm_atomic_helper_plane_reset,
- .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = drm_plane_cleanup,
+ DRM_GEM_SHADOW_PLANE_FUNCS
};
static void bochs_crtc_helper_mode_set_nofb(struct drm_crtc *crtc)
@@ -557,8 +559,7 @@ static const struct drm_connector_funcs bochs_connector_funcs = {
};
static const struct drm_mode_config_funcs bochs_mode_config_funcs = {
- .fb_create = drm_gem_fb_create,
- .mode_valid = drm_vram_helper_mode_valid,
+ .fb_create = drm_gem_fb_create_with_dirty,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
@@ -629,17 +630,12 @@ static int bochs_kms_init(struct bochs_device *bochs)
static int bochs_load(struct bochs_device *bochs)
{
- struct drm_device *dev = &bochs->dev;
int ret;
ret = bochs_hw_init(bochs);
if (ret)
return ret;
- ret = drmm_vram_helper_init(dev, bochs->fb_base, bochs->fb_size);
- if (ret)
- return ret;
-
ret = bochs_kms_init(bochs);
if (ret)
return ret;
@@ -657,7 +653,7 @@ static const struct drm_driver bochs_driver = {
.date = "20130925",
.major = 1,
.minor = 0,
- DRM_GEM_VRAM_DRIVER,
+ DRM_GEM_SHMEM_DRIVER_OPS,
};
/* ---------------------------------------------------------------------- */
@@ -723,7 +719,7 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent
if (ret)
goto err_free_dev;
- drm_fbdev_ttm_setup(dev, 32);
+ drm_fbdev_shmem_setup(dev, 32);
return ret;
err_free_dev:
--
2.46.0
next prev parent reply other threads:[~2024-08-23 12:44 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-23 12:28 [PATCH 00/10] rm/bochs: Modernize driver Thomas Zimmermann
2024-08-23 12:28 ` [PATCH 01/10] drm/bochs: Remove manual format test from fb_create Thomas Zimmermann
2024-08-23 12:28 ` [PATCH 02/10] drm/bochs: Use helpers for struct drm_edid Thomas Zimmermann
2024-08-23 12:28 ` [PATCH 03/10] drm/bochs: Do managed resource cleanup Thomas Zimmermann
2024-08-23 12:28 ` [PATCH 04/10] drm/bochs: Pass bochs device to various functions Thomas Zimmermann
2024-08-23 12:28 ` [PATCH 05/10] drm/bochs: Upcast with to_bochs_device() Thomas Zimmermann
2024-08-23 12:28 ` [PATCH 06/10] drm/bochs: Allocate DRM device in struct bochs_device Thomas Zimmermann
2024-08-23 12:28 ` [PATCH 07/10] drm/bochs: Use regular atomic helpers Thomas Zimmermann
2024-08-23 12:28 ` Thomas Zimmermann [this message]
2024-08-23 12:28 ` [PATCH 09/10] drm/bochs: Validate display modes against available video memory Thomas Zimmermann
2024-08-29 20:37 ` kernel test robot
2024-08-23 12:28 ` [PATCH 10/10] drm/gem-vram: Remove support for simple display pipelines Thomas Zimmermann
2024-08-23 14:34 ` [PATCH 00/10] rm/bochs: Modernize driver Gerd Hoffmann
2024-08-23 15:00 ` Thomas Zimmermann
2024-08-26 7:32 ` Gerd Hoffmann
2024-08-26 8:08 ` Thomas Zimmermann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240823124422.286989-9-tzimmermann@suse.de \
--to=tzimmermann@suse.de \
--cc=airlied@gmail.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=kraxel@redhat.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=virtualization@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox