From: Tormod Volden debian.tormod@gmail.com
Subject: [PATCH] drm: Add flag for multiple framebuffer support
Do not ignore the offset when looking for existing framebuffer maps if the new _DRM_MATCH_FB_OFFSET flag is passed to drm_addmap_core. ---
In commit 41c2e75e60200a860a74b7c84a6375c105e7437f "drm: Make drm_local_map use a resource_size_t offset" [1] the support for multiple _DRM_FRAMEBUFFER maps per device was taken away. This change made the savage drivers upset, since these cards have several apertures (the layout is different between card families) for which the kernel drm driver sets up maps. And these maps are now mixed up into one broken one.
The drivers (drm, ddx, mesa) for instance expects a framebuffer map and a tiled aperture map, and the broken maps show up as rendering corruption [2] and allocation failures. I have tried to come up with userland workarounds but it seems impossible since the kernel will only return the handle to a broken map and there is no way to remap it correctly.
Would it be possible to reintroduce this support? One solution could be a new flag _DRM_IGNORE_FB_OFFSET that can be used by those drivers that need it, or the other way around, a _DRM_CHECK_FB_OFFSET to be added by the savage drivers and others in the same situation. I can of course try to write a patch if people think this is a good idea.
This was what I had in mind. Probably controversial to add a new flag for this, so more elegant ideas are welcome.
Cheers, Tormod
drivers/gpu/drm/drm_bufs.c | 4 +++- include/drm/drm.h | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 3e257a5..9b7b257 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -60,8 +60,10 @@ static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, if (map->flags != _DRM_CONTAINS_LOCK) break; case _DRM_REGISTERS: - case _DRM_FRAME_BUFFER: return entry; + case _DRM_FRAME_BUFFER: + if (!(map->flags & _DRM_MATCH_FB_OFFSET)) + return entry; default: /* Make gcc happy */ ; } diff --git a/include/drm/drm.h b/include/drm/drm.h index 4be33b4..d4e2560 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -195,7 +195,8 @@ enum drm_map_flags { _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ _DRM_REMOVABLE = 0x40, /**< Removable mapping */ - _DRM_DRIVER = 0x80 /**< Managed by driver */ + _DRM_DRIVER = 0x80, /**< Managed by driver */ + _DRM_MATCH_FB_OFFSET = 0x100 /**< Multiple framebuffer support */ };
struct drm_ctx_priv_map {