From: Michel Dänzer <[email protected]>

Needed for Xorg -background none.

(Ported from radeon commit 3999bf88cdb192fe2f30b03bd2ed6f6a3f9f9057)

Signed-off-by: Michel Dänzer <[email protected]>
---
 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

_______________________________________________
xorg-driver-ati mailing list
[email protected]
http://lists.x.org/mailman/listinfo/xorg-driver-ati

Reply via email to