[PATCH xf86-video-amdgpu 5/6] Make drmmode_copy_fb() work with glamor
Michel Dänzer
michel at daenzer.net
Thu Aug 6 02:59:35 PDT 2015
From: Michel Dänzer <michel.daenzer at amd.com>
Needed for Xorg -background none.
(Ported from radeon commit 3999bf88cdb192fe2f30b03bd2ed6f6a3f9f9057)
Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
src/amdgpu_drv.h | 1 +
src/amdgpu_kms.c | 7 +++-
src/drmmode_display.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 113 insertions(+), 8 deletions(-)
diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
index c7bc4f3..7194a48 100644
--- a/src/amdgpu_drv.h
+++ b/src/amdgpu_drv.h
@@ -202,6 +202,7 @@ typedef struct {
struct amdgpu_dri2 dri2;
/* accel */
+ PixmapPtr fbcon_pixmap;
uint_fast32_t gpu_flushed;
uint_fast32_t gpu_synced;
Bool use_glamor;
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index cc88e2c..1cc945e 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -112,6 +112,9 @@ static void AMDGPUFreeRec(ScrnInfoPtr pScrn)
info = AMDGPUPTR(pScrn);
+ if (info->fbcon_pixmap)
+ pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap);
+
if (info->dri2.drm_fd > 0) {
DevUnion *pPriv;
AMDGPUEntPtr pAMDGPUEnt;
@@ -1193,7 +1196,7 @@ Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
pScrn->pScreen = pScreen;
#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
- if (bgNoneRoot) {
+ if (bgNoneRoot && info->use_glamor) {
info->CreateWindow = pScreen->CreateWindow;
pScreen->CreateWindow = AMDGPUCreateWindow;
}
@@ -1256,7 +1259,7 @@ Bool AMDGPUEnterVT_KMS(VT_FUNC_ARGS_DECL)
pScrn->vtSema = TRUE;
#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
- if (bgNoneRoot)
+ if (bgNoneRoot && info->use_glamor)
drmmode_copy_fb(pScrn, &info->drmmode);
#endif
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 3c8e231..161c2ca 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -314,16 +314,117 @@ drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
-/* TODO: currently this function only clear the front buffer to zero */
-/* Moving forward, we might to look into making the copy with glamor instead */
+static PixmapPtr
+create_pixmap_for_fbcon(drmmode_ptr drmmode,
+ ScrnInfoPtr pScrn, int fbcon_id)
+{
+ AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
+ AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
+ PixmapPtr pixmap = info->fbcon_pixmap;
+ struct amdgpu_buffer *bo;
+ drmModeFBPtr fbcon;
+ struct drm_gem_flink flink;
+ struct amdgpu_bo_import_result import = {0};
+
+ if (pixmap)
+ return pixmap;
+
+ fbcon = drmModeGetFB(drmmode->fd, fbcon_id);
+ if (fbcon == NULL)
+ return NULL;
+
+ if (fbcon->depth != pScrn->depth ||
+ fbcon->width != pScrn->virtualX ||
+ fbcon->height != pScrn->virtualY)
+ goto out_free_fb;
+
+ flink.handle = fbcon->handle;
+ if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't flink fbcon handle\n");
+ goto out_free_fb;
+ }
+
+ bo = calloc(1, sizeof(struct amdgpu_buffer));
+ if (bo == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't allocate bo for fbcon handle\n");
+ goto out_free_fb;
+ }
+ bo->ref_count = 1;
+
+ if (amdgpu_bo_import(pAMDGPUEnt->pDev,
+ amdgpu_bo_handle_type_gem_flink_name, flink.name,
+ &import) != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't import BO for fbcon handle\n");
+ goto out_free_bo;
+ }
+ bo->bo.amdgpu = import.buf_handle;
+
+ pixmap = drmmode_create_bo_pixmap(pScrn, fbcon->width, fbcon->height,
+ fbcon->depth, fbcon->bpp,
+ fbcon->pitch, bo);
+ info->fbcon_pixmap = pixmap;
+out_free_bo:
+ amdgpu_bo_unref(&bo);
+out_free_fb:
+ drmModeFreeFB(fbcon);
+ return pixmap;
+}
+
void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
- uint32_t size = pScrn->displayWidth * info->pixel_bytes * pScrn->virtualY;
+ PixmapPtr src, dst;
+ ScreenPtr pScreen = pScrn->pScreen;
+ int fbcon_id = 0;
+ GCPtr gc;
+ int i;
+
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[i]->driver_private;
+
+ if (drmmode_crtc->mode_crtc->buffer_id)
+ fbcon_id = drmmode_crtc->mode_crtc->buffer_id;
+ }
+
+ if (!fbcon_id)
+ return;
+
+ if (fbcon_id == drmmode->fb_id) {
+ /* in some rare case there might be no fbcon and we might already
+ * be the one with the current fb to avoid a false deadlck in
+ * kernel ttm code just do nothing as anyway there is nothing
+ * to do
+ */
+ return;
+ }
+
+ src = create_pixmap_for_fbcon(drmmode, pScrn, fbcon_id);
+ if (!src)
+ return;
+
+ dst = pScreen->GetScreenPixmap(pScreen);
+
+ gc = GetScratchGC(pScrn->depth, pScreen);
+ ValidateGC(&dst->drawable, gc);
+
+ (*gc->ops->CopyArea)(&src->drawable, &dst->drawable, gc, 0, 0,
+ pScrn->virtualX, pScrn->virtualY, 0, 0);
+
+ FreeScratchGC(gc);
+
+ amdgpu_glamor_flush(pScrn);
+
+ pScreen->canDoBGNoneRoot = TRUE;
+
+ if (info->fbcon_pixmap)
+ pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap);
+ info->fbcon_pixmap = NULL;
- /* memset the bo */
- amdgpu_bo_map(pScrn, info->front_buffer);
- memset(info->front_buffer->cpu_ptr, 0x00, size);
+ return;
}
#endif /* GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10 */
--
2.5.0
More information about the xorg-driver-ati
mailing list