From 649644a88347a6d03de68f8c41db03a82deeb23b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 14 Feb 2017 17:36:31 +0900 Subject: Factor out radeon_prime_dirty_to_crtc helper Cleanup in preparation for the following change, no functional change intended. Reviewed-by: Alex Deucher --- src/radeon_kms.c | 62 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index a95b51ab..0ed7680e 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -643,6 +643,27 @@ call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) #endif /* HAS_SYNC_SHARED_PIXMAPS */ +static xf86CrtcPtr +radeon_prime_dirty_to_crtc(PixmapDirtyUpdatePtr dirty) +{ + ScreenPtr screen = dirty->slave_dst->drawable.pScreen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + /* Find the CRTC which is scanning out from this slave pixmap */ + for (c = 0; c < xf86_config->num_crtc; c++) { + xf86CrtcPtr xf86_crtc = xf86_config->crtc[c]; + drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; + + if (drmmode_crtc->scanout[0].pixmap == dirty->slave_dst || + drmmode_crtc->scanout[1].pixmap == dirty->slave_dst) + return xf86_crtc; + } + + return NULL; +} + static Bool radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id) { @@ -701,24 +722,16 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) { ScreenPtr screen = dirty->slave_dst->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - xf86CrtcPtr xf86_crtc = NULL; - drmmode_crtc_private_ptr drmmode_crtc = NULL; + xf86CrtcPtr xf86_crtc = radeon_prime_dirty_to_crtc(dirty); + drmmode_crtc_private_ptr drmmode_crtc; uintptr_t drm_queue_seq; drmVBlank vbl; - int c; - /* Find the CRTC which is scanning out from this slave pixmap */ - for (c = 0; c < xf86_config->num_crtc; c++) { - xf86_crtc = xf86_config->crtc[c]; - drmmode_crtc = xf86_crtc->driver_private; - if (drmmode_crtc->scanout[0].pixmap == dirty->slave_dst) - break; - } + if (!xf86_crtc || !xf86_crtc->enabled) + return; - if (c == xf86_config->num_crtc || - !xf86_crtc->enabled || - drmmode_crtc->scanout_update_pending || + drmmode_crtc = xf86_crtc->driver_private; + if (drmmode_crtc->scanout_update_pending || !drmmode_crtc->scanout[0].pixmap || drmmode_crtc->pending_dpms_mode != DPMSModeOn) return; @@ -764,25 +777,16 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) ScreenPtr screen = ent->slave_dst->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - xf86CrtcPtr crtc = NULL; - drmmode_crtc_private_ptr drmmode_crtc = NULL; + xf86CrtcPtr crtc = radeon_prime_dirty_to_crtc(ent); + drmmode_crtc_private_ptr drmmode_crtc; uintptr_t drm_queue_seq; unsigned scanout_id; - int c; - /* Find the CRTC which is scanning out from this slave pixmap */ - for (c = 0; c < xf86_config->num_crtc; c++) { - crtc = xf86_config->crtc[c]; - drmmode_crtc = crtc->driver_private; - scanout_id = drmmode_crtc->scanout_id; - if (drmmode_crtc->scanout[scanout_id].pixmap == ent->slave_dst) - break; - } + if (!crtc || !crtc->enabled) + return; - if (c == xf86_config->num_crtc || - !crtc->enabled || - drmmode_crtc->scanout_update_pending || + drmmode_crtc = crtc->driver_private; + if (drmmode_crtc->scanout_update_pending || !drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap || drmmode_crtc->pending_dpms_mode != DPMSModeOn) return; -- cgit v1.2.3 From 305e2cbf335837a2ab6a24e9ff65815afe038296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 21 Feb 2017 15:55:13 +0900 Subject: Factor out drmmode_crtc_scanout_update helper Cleanup in preparation for following change, no functional change intended. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 85 +++++++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 2258e7a6..fcac1562 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -706,6 +706,53 @@ drmmode_handle_transform(xf86CrtcPtr crtc) #endif +static void +drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, + unsigned scanout_id, int *fb_id, int *x, int *y) +{ + ScrnInfoPtr scrn = crtc->scrn; + ScreenPtr screen = scrn->pScreen; + RADEONInfoPtr info = RADEONPTR(scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0], + mode->HDisplay, mode->VDisplay); + if (info->tear_free) { + drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], + mode->HDisplay, mode->VDisplay); + } + + if (drmmode_crtc->scanout[0].pixmap && + (!info->tear_free || drmmode_crtc->scanout[1].pixmap)) { + RegionPtr region; + BoxPtr box; + + if (!drmmode_crtc->scanout_damage) { + drmmode_crtc->scanout_damage = + DamageCreate(radeon_screen_damage_report, + NULL, DamageReportRawRegion, + TRUE, screen, NULL); + DamageRegister(&screen->GetScreenPixmap(screen)->drawable, + drmmode_crtc->scanout_damage); + } + + region = DamageRegion(drmmode_crtc->scanout_damage); + RegionUninit(region); + region->data = NULL; + box = RegionExtents(region); + box->x1 = 0; + box->y1 = 0; + box->x2 = max(box->x2, scrn->virtualX); + box->y2 = max(box->y2, scrn->virtualY); + + *fb_id = drmmode_crtc->scanout[scanout_id].fb_id; + *x = *y = 0; + + radeon_scanout_do_update(crtc, scanout_id); + radeon_bo_wait(drmmode_crtc->scanout[scanout_id].bo); + } +} + static Bool drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y) @@ -779,42 +826,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, crtc->driverIsPerformingTransform || #endif info->shadow_primary)) { - for (i = 0; i < (info->tear_free ? 2 : 1); i++) { - drmmode_crtc_scanout_create(crtc, - &drmmode_crtc->scanout[i], - mode->HDisplay, - mode->VDisplay); - } - - if (drmmode_crtc->scanout[0].pixmap && - (!info->tear_free || drmmode_crtc->scanout[1].pixmap)) { - RegionPtr pRegion; - BoxPtr pBox; - - if (!drmmode_crtc->scanout_damage) { - drmmode_crtc->scanout_damage = - DamageCreate(radeon_screen_damage_report, - NULL, DamageReportRawRegion, - TRUE, pScreen, NULL); - DamageRegister(&pScreen->GetScreenPixmap(pScreen)->drawable, - drmmode_crtc->scanout_damage); - } - - pRegion = DamageRegion(drmmode_crtc->scanout_damage); - RegionUninit(pRegion); - pRegion->data = NULL; - pBox = RegionExtents(pRegion); - pBox->x1 = 0; - pBox->y1 = 0; - pBox->x2 = max(pBox->x2, pScrn->virtualX); - pBox->y2 = max(pBox->y2, pScrn->virtualY); - - fb_id = drmmode_crtc->scanout[scanout_id].fb_id; - x = y = 0; - - radeon_scanout_do_update(crtc, scanout_id); - radeon_bo_wait(drmmode_crtc->scanout[scanout_id].bo); - } + drmmode_crtc_scanout_update(crtc, mode, scanout_id, + &fb_id, &x, &y); } if (fb_id == 0) { -- cgit v1.2.3 From 58cd1600057e41aade0106d4acf78e23eac6e44f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 1 Dec 2016 18:37:57 +0900 Subject: Allow toggling TearFree at runtime via output property Option "TearFree" now sets the default value of the output property. See the manpage update for details. TearFree is now enabled by default for outputs using rotation or other RandR transforms, and for RandR 1.4 slave outputs. Reviewed-by: Alex Deucher --- man/radeon.man | 15 +++-- src/drmmode_display.c | 161 +++++++++++++++++++++++++++++++++++++++++++++----- src/drmmode_display.h | 2 + src/radeon.h | 2 +- src/radeon_dri2.c | 35 ++++++++--- src/radeon_kms.c | 43 +++++++++----- 6 files changed, 216 insertions(+), 42 deletions(-) diff --git a/man/radeon.man b/man/radeon.man index 8990ae21..5301dd7f 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -281,10 +281,17 @@ Enable DRI2 page flipping. The default is Pageflipping is supported on all radeon hardware. .TP .BI "Option \*qTearFree\*q \*q" boolean \*q -Enable tearing prevention using the hardware page flipping mechanism. Requires allocating two -separate scanout buffers for each CRTC. Enabling this option currently disables Option -\*qEnablePageFlip\*q. The default is -.B off. +Set the default value of the per-output 'TearFree' property, which controls +tearing prevention using the hardware page flipping mechanism. TearFree is +on for any CRTC associated with one or more outputs with TearFree on. Two +separate scanout buffers need to be allocated for each CRTC with TearFree +on. While TearFree is on for any CRTC, it currently prevents clients from using +DRI page flipping. If this option is set, the default value of the property is +'on' or 'off' accordingly. If this option isn't set, the default value of the +property is +.B auto, +which means that TearFree is on for outputs with rotation or other RandR +transforms, and for RandR 1.4 slave outputs, otherwise off. .TP .BI "Option \*qAccelMethod\*q \*q" "string" \*q Chooses between available acceleration architectures. Valid values are diff --git a/src/drmmode_display.c b/src/drmmode_display.c index fcac1562..5b0236da 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -670,6 +670,34 @@ drmmode_can_use_hw_cursor(xf86CrtcPtr crtc) return TRUE; } +static void +drmmode_crtc_update_tear_free(xf86CrtcPtr crtc) +{ + RADEONInfoPtr info = RADEONPTR(crtc->scrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + int i; + + drmmode_crtc->tear_free = FALSE; + + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + drmmode_output_private_ptr drmmode_output = output->driver_private; + + if (output->crtc != crtc) + continue; + + if (drmmode_output->tear_free == 1 || + (drmmode_output->tear_free == 2 && + (radeon_is_gpu_screen(crtc->scrn->pScreen) || + info->shadow_primary || + crtc->transformPresent || crtc->rotation != RR_Rotate_0))) { + drmmode_crtc->tear_free = TRUE; + return; + } + } +} + #if XF86_CRTC_VERSION >= 4 static Bool @@ -683,10 +711,11 @@ drmmode_handle_transform(xf86CrtcPtr crtc) else crtc->driverIsPerformingTransform = XF86DriverTransformNone; #else + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; RADEONInfoPtr info = RADEONPTR(crtc->scrn); crtc->driverIsPerformingTransform = crtc->transformPresent || - (info->tear_free && crtc->rotation != RR_Rotate_0); + (drmmode_crtc->tear_free && crtc->rotation != RR_Rotate_0); #endif ret = xf86CrtcRotate(crtc); @@ -706,24 +735,87 @@ drmmode_handle_transform(xf86CrtcPtr crtc) #endif +#ifdef RADEON_PIXMAP_SHARING + static void +drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, + unsigned scanout_id, int *fb_id, int *x, + int *y) +{ + ScrnInfoPtr scrn = crtc->scrn; + ScreenPtr screen = scrn->pScreen; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + if (drmmode_crtc->tear_free && + !drmmode_crtc->scanout[1].pixmap) { + RegionPtr region; + BoxPtr box; + + drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], + mode->HDisplay, + mode->VDisplay); + region = &drmmode_crtc->scanout_last_region; + RegionUninit(region); + region->data = NULL; + box = RegionExtents(region); + box->x1 = crtc->x; + box->y1 = crtc->y; + box->x2 = crtc->x + mode->HDisplay; + box->y2 = crtc->y + mode->VDisplay; + } + + if (scanout_id != drmmode_crtc->scanout_id) { + PixmapDirtyUpdatePtr dirty = NULL; + + xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, + ent) { + if (dirty->src == crtc->randr_crtc->scanout_pixmap && + dirty->slave_dst == + drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap) { + dirty->slave_dst = + drmmode_crtc->scanout[scanout_id].pixmap; + break; + } + } + + if (!drmmode_crtc->tear_free) { + GCPtr gc = GetScratchGC(scrn->depth, screen); + + ValidateGC(&drmmode_crtc->scanout[0].pixmap->drawable, gc); + gc->ops->CopyArea(&drmmode_crtc->scanout[1].pixmap->drawable, + &drmmode_crtc->scanout[0].pixmap->drawable, + gc, 0, 0, mode->HDisplay, mode->VDisplay, + 0, 0); + FreeScratchGC(gc); + radeon_cs_flush_indirect(scrn); + radeon_bo_wait(drmmode_crtc->scanout[0].bo); + } + } + + *fb_id = drmmode_crtc->scanout[scanout_id].fb_id; + *x = *y = 0; + drmmode_crtc->scanout_id = scanout_id; +} + +#endif /* RADEON_PIXMAP_SHARING */ + + static void drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, unsigned scanout_id, int *fb_id, int *x, int *y) { ScrnInfoPtr scrn = crtc->scrn; ScreenPtr screen = scrn->pScreen; - RADEONInfoPtr info = RADEONPTR(scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0], mode->HDisplay, mode->VDisplay); - if (info->tear_free) { + if (drmmode_crtc->tear_free) { drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], mode->HDisplay, mode->VDisplay); } if (drmmode_crtc->scanout[0].pixmap && - (!info->tear_free || drmmode_crtc->scanout[1].pixmap)) { + (!drmmode_crtc->tear_free || drmmode_crtc->scanout[1].pixmap)) { RegionPtr region; BoxPtr box; @@ -762,7 +854,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, RADEONInfoPtr info = RADEONPTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - unsigned scanout_id = drmmode_crtc->scanout_id ^ info->tear_free; + unsigned scanout_id = 0; drmmode_ptr drmmode = drmmode_crtc->drmmode; int saved_x, saved_y; Rotation saved_rotation; @@ -804,6 +896,10 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, if (!drmmode_handle_transform(crtc)) goto done; + drmmode_crtc_update_tear_free(crtc); + if (drmmode_crtc->tear_free) + scanout_id = drmmode_crtc->scanout_id; + crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, crtc->gamma_blue, crtc->gamma_size); @@ -812,8 +908,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, fb_id = drmmode->fb_id; #ifdef RADEON_PIXMAP_SHARING if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) { - fb_id = drmmode_crtc->scanout[scanout_id].fb_id; - x = y = 0; + drmmode_crtc_prime_scanout_update(crtc, mode, scanout_id, + &fb_id, &x, &y); } else #endif if (drmmode_crtc->rotate.fb_id) { @@ -821,7 +917,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, x = y = 0; } else if (!radeon_is_gpu_screen(pScreen) && - (info->tear_free || + (drmmode_crtc->tear_free || #if XF86_CRTC_VERSION >= 4 crtc->driverIsPerformingTransform || #endif @@ -905,6 +1001,10 @@ done: if (fb_id != drmmode_crtc->scanout[scanout_id].fb_id) drmmode_crtc_scanout_free(drmmode_crtc); + else if (!drmmode_crtc->tear_free) { + drmmode_crtc_scanout_destroy(drmmode, + &drmmode_crtc->scanout[1]); + } } free(output_ids); @@ -1142,7 +1242,6 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; unsigned scanout_id = drmmode_crtc->scanout_id; - RADEONInfoPtr info = RADEONPTR(crtc->scrn); ScreenPtr screen = crtc->scrn->pScreen; PixmapDirtyUpdatePtr dirty; @@ -1163,7 +1262,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) ppix->drawable.height)) return FALSE; - if (info->tear_free && + if (drmmode_crtc->tear_free && !drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], ppix->drawable.width, ppix->drawable.height)) { @@ -1418,13 +1517,14 @@ drmmode_property_ignore(drmModePropertyPtr prop) static void drmmode_output_create_resources(xf86OutputPtr output) { + RADEONInfoPtr info = RADEONPTR(output->scrn); drmmode_output_private_ptr drmmode_output = output->driver_private; drmModeConnectorPtr mode_output = drmmode_output->mode_output; drmmode_ptr drmmode = drmmode_output->drmmode; - drmModePropertyPtr drmmode_prop; + drmModePropertyPtr drmmode_prop, tearfree_prop; int i, j, err; - drmmode_output->props = calloc(mode_output->count_props, sizeof(drmmode_prop_rec)); + drmmode_output->props = calloc(mode_output->count_props + 1, sizeof(drmmode_prop_rec)); if (!drmmode_output->props) return; @@ -1441,6 +1541,23 @@ drmmode_output_create_resources(xf86OutputPtr output) j++; } + /* Userspace-only property for TearFree */ + tearfree_prop = calloc(1, sizeof(*tearfree_prop)); + tearfree_prop->flags = DRM_MODE_PROP_ENUM; + strncpy(tearfree_prop->name, "TearFree", 8); + tearfree_prop->count_enums = 3; + tearfree_prop->enums = calloc(tearfree_prop->count_enums, + sizeof(*tearfree_prop->enums)); + strncpy(tearfree_prop->enums[0].name, "off", 3); + strncpy(tearfree_prop->enums[1].name, "on", 2); + tearfree_prop->enums[1].value = 1; + strncpy(tearfree_prop->enums[2].name, "auto", 4); + tearfree_prop->enums[2].value = 2; + drmmode_output->props[j].mode_prop = tearfree_prop; + drmmode_output->props[j].value = info->tear_free; + drmmode_output->tear_free = info->tear_free; + drmmode_output->num_props++; + for (i = 0; i < drmmode_output->num_props; i++) { drmmode_prop_ptr p = &drmmode_output->props[i]; drmmode_prop = p->mode_prop; @@ -1540,8 +1657,24 @@ drmmode_output_set_property(xf86OutputPtr output, Atom property, /* search for matching name string, then set its value down */ for (j = 0; j < p->mode_prop->count_enums; j++) { if (!strcmp(p->mode_prop->enums[j].name, name)) { - drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, - p->mode_prop->prop_id, p->mode_prop->enums[j].value); + if (i == (drmmode_output->num_props - 1)) { + if (drmmode_output->tear_free != j) { + xf86CrtcPtr crtc = output->crtc; + + drmmode_output->tear_free = j; + if (crtc) { + drmmode_set_mode_major(crtc, &crtc->mode, + crtc->rotation, + crtc->x, crtc->y); + } + } + } else { + drmModeConnectorSetProperty(drmmode->fd, + drmmode_output->output_id, + p->mode_prop->prop_id, + p->mode_prop->enums[j].value); + } + return TRUE; } } diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 6bbf71c1..bd3f5f98 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -89,6 +89,7 @@ typedef struct { RegionRec scanout_last_region; unsigned scanout_id; Bool scanout_update_pending; + Bool tear_free; int dpms_mode; /* For when a flip is pending when DPMS off requested */ int pending_dpms_mode; @@ -124,6 +125,7 @@ typedef struct { drmmode_prop_ptr props; int enc_mask; int enc_clone_mask; + int tear_free; } drmmode_output_private_rec, *drmmode_output_private_ptr; diff --git a/src/radeon.h b/src/radeon.h index 039a620b..bfff232c 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -507,7 +507,7 @@ typedef struct { Bool accelOn; Bool use_glamor; Bool shadow_primary; - Bool tear_free; + int tear_free; Bool exa_pixmaps; Bool exa_force_create; XF86ModReqInfo exaReq; diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index d0dcf890..c108ceab 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -47,6 +47,7 @@ #include "radeon_bo_gem.h" #include +#include #if DRI2INFOREC_VERSION >= 9 #define USE_DRI2_PRIME @@ -756,14 +757,34 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back) { RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int num_crtcs_on; + int i; + + if (draw->type != DRAWABLE_WINDOW || + !info->allowPageFlip || + info->hwcursor_disabled || + info->drmmode.present_flipping || + !pScrn->vtSema || + !DRI2CanFlip(draw)) + return FALSE; + + for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) { + xf86CrtcPtr crtc = config->crtc[i]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + if (!crtc->enabled) + continue; + + if (!drmmode_crtc || drmmode_crtc->rotate.bo || + drmmode_crtc->scanout[0].bo) + return FALSE; + + if (drmmode_crtc->pending_dpms_mode == DPMSModeOn) + num_crtcs_on++; + } - return draw->type == DRAWABLE_WINDOW && - info->allowPageFlip && - !info->hwcursor_disabled && - !info->drmmode.present_flipping && - pScrn->vtSema && - DRI2CanFlip(draw) && - can_exchange(pScrn, draw, front, back); + return num_crtcs_on > 0 && can_exchange(pScrn, draw, front, back); } static void diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 0ed7680e..331f3f1c 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -669,7 +669,6 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id) { ScrnInfoPtr scrn = crtc->scrn; ScreenPtr screen = scrn->pScreen; - RADEONInfoPtr info = RADEONPTR(scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap; PixmapDirtyUpdatePtr dirty; @@ -677,7 +676,7 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id) xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { if (dirty->src == scanoutpix && dirty->slave_dst == - drmmode_crtc->scanout[scanout_id ^ info->tear_free].pixmap) { + drmmode_crtc->scanout[scanout_id ^ drmmode_crtc->tear_free].pixmap) { RegionPtr region; if (master_has_sync_shared_pixmap(scrn, dirty)) @@ -687,7 +686,7 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id) if (RegionNil(region)) goto destroy; - if (info->tear_free) { + if (drmmode_crtc->tear_free) { RegionTranslate(region, crtc->x, crtc->y); radeon_sync_scanout_pixmaps(crtc, region, scanout_id); radeon_cs_flush_indirect(scrn); @@ -823,7 +822,6 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) static void radeon_dirty_update(ScrnInfoPtr scrn) { - RADEONInfoPtr info = RADEONPTR(scrn); ScreenPtr screen = scrn->pScreen; PixmapDirtyUpdatePtr ent; RegionPtr region; @@ -844,7 +842,13 @@ radeon_dirty_update(ScrnInfoPtr scrn) region = dirty_region(region_ent); if (RegionNotEmpty(region)) { - if (info->tear_free) + xf86CrtcPtr crtc = radeon_prime_dirty_to_crtc(ent); + drmmode_crtc_private_ptr drmmode_crtc = NULL; + + if (crtc) + drmmode_crtc = crtc->driver_private; + + if (drmmode_crtc && drmmode_crtc->tear_free) radeon_prime_scanout_flip(ent); else radeon_prime_scanout_update(ent); @@ -890,7 +894,7 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id) if (!radeon_scanout_extents_intersect(xf86_crtc, &extents)) return FALSE; - if (info->tear_free) { + if (drmmode_crtc->tear_free) { radeon_sync_scanout_pixmaps(xf86_crtc, pRegion, scanout_id); RegionCopy(&drmmode_crtc->scanout_last_region, pRegion); } @@ -1112,14 +1116,17 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) if (!radeon_is_gpu_screen(pScreen)) { for (c = 0; c < xf86_config->num_crtc; c++) { - if (info->tear_free) - radeon_scanout_flip(pScreen, info, xf86_config->crtc[c]); + xf86CrtcPtr crtc = xf86_config->crtc[c]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + if (drmmode_crtc->tear_free) + radeon_scanout_flip(pScreen, info, crtc); else if (info->shadow_primary #if XF86_CRTC_VERSION >= 4 - || xf86_config->crtc[c]->driverIsPerformingTransform + || crtc->driverIsPerformingTransform #endif ) - radeon_scanout_update(xf86_config->crtc[c]); + radeon_scanout_update(crtc); } } @@ -1633,6 +1640,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) { RADEONInfoPtr info; RADEONEntPtr pRADEONEnt; + MessageType from; DevUnion* pPriv; Gamma zeros = { 0.0, 0.0, 0.0 }; uint32_t tiling = 0; @@ -1778,11 +1786,14 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) #endif if (!info->r600_shadow_fb) { - info->tear_free = xf86ReturnOptValBool(info->Options, OPTION_TEAR_FREE, - FALSE); + from = X_DEFAULT; - if (info->tear_free) - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TearFree enabled\n"); + info->tear_free = 2; + if (xf86GetOptValBool(info->Options, OPTION_TEAR_FREE, + &info->tear_free)) + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, from, "TearFree property default: %s\n", + info->tear_free == 2 ? "auto" : (info->tear_free ? "on" : "off")); } if (info->dri2.pKernelDRMVersion->version_minor >= 8) { @@ -1791,13 +1802,13 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) info->allowPageFlip = xf86ReturnOptValBool(info->Options, OPTION_PAGE_FLIP, TRUE); - if (sw_cursor || info->tear_free || info->shadow_primary) { + if (sw_cursor || info->shadow_primary) { xf86DrvMsg(pScrn->scrnIndex, info->allowPageFlip ? X_WARNING : X_DEFAULT, "KMS Pageflipping: disabled%s\n", info->allowPageFlip ? (sw_cursor ? " because of SWcursor" : - " because of ShadowPrimary/TearFree") : ""); + " because of ShadowPrimary") : ""); info->allowPageFlip = FALSE; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, -- cgit v1.2.3 From 0c29deb5a97d9a57e994cc0053c49ddf7aca6ecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 21 Feb 2017 16:56:27 +0900 Subject: Use drmmode_crtc_scanout_free in drmmode_fini We were leaking drmmode_crtc->scanout_damage, which caused trouble on server reset. Fixes server reset with active separate scanout pixmaps. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 5b0236da..fd22a19b 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2618,13 +2618,8 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode) #endif } - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - - drmmode_crtc_scanout_destroy(&info->drmmode, &drmmode_crtc->scanout[0]); - drmmode_crtc_scanout_destroy(&info->drmmode, &drmmode_crtc->scanout[1]); - } + for (c = 0; c < config->num_crtc; c++) + drmmode_crtc_scanout_free(config->crtc[c]->driver_private); } -- cgit v1.2.3 From 3ff29e5a14451916bc66b4e0028e9a317f0723f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 9 Feb 2017 18:50:40 +0900 Subject: present: Only call drmModeRmFB after setting modes for unflip Fixes display intermittently blanking when a modeset is used for unflip. Reviewed-by: Alex Deucher --- src/radeon_present.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/radeon_present.c b/src/radeon_present.c index 29800fec..b36e29b1 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -371,6 +371,7 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) struct radeon_present_vblank_event *event; PixmapPtr pixmap = screen->GetScreenPixmap(screen); uint32_t handle; + int old_fb_id; int i; if (!radeon_present_check_unflip(scrn)) @@ -400,7 +401,7 @@ modeset: /* info->drmmode.fb_id still points to the FB for the last flipped BO. * Clear it, drmmode_set_mode_major will re-create it */ - drmModeRmFB(info->drmmode.fd, info->drmmode.fb_id); + old_fb_id = info->drmmode.fb_id; info->drmmode.fb_id = 0; for (i = 0; i < config->num_crtc; i++) { @@ -417,6 +418,7 @@ modeset: drmmode_crtc->need_modeset = TRUE; } + drmModeRmFB(info->drmmode.fd, old_fb_id); present_event_notify(event_id, 0, 0); info->drmmode.present_flipping = FALSE; -- cgit v1.2.3 From 244d4bc7f8c8f6bc90f49556c0b9344c8aa40295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 9 Feb 2017 18:55:04 +0900 Subject: present: Wait for screen pixmap BO idle before setting modes for unflip To make sure the screen pixmap contents are up to date when it starts being scanned out. Reviewed-by: Alex Deucher --- src/radeon_present.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/radeon_present.c b/src/radeon_present.c index b36e29b1..1b0ddcb8 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -404,6 +404,8 @@ modeset: old_fb_id = info->drmmode.fb_id; info->drmmode.fb_id = 0; + radeon_cs_flush_indirect(scrn); + radeon_bo_wait(info->front_bo); for (i = 0; i < config->num_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; -- cgit v1.2.3 From 987a34adb319923ad36e2b47a26837248f187c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 28 Feb 2017 17:17:20 +0900 Subject: Call drmmode_crtc_scanout_create in drmmode_crtc_shadow_allocate as well Calling drmmode_crtc_scanout_allocate in drmmode_crtc_shadow_allocate resulted in drmmode_crtc_scanout_create called from drmmode_crtc_shadow_create passing an uninitialized pitch value to drmmode_create_bo_pixmap. Fixes issues such as failure to allocate the scanout pixmap or visual corruption and GPUVM faults when attempting to use rotation with Xorg <1.19. Bugzilla: https://bugs.freedesktop.org/99916 Fixes: ea30d856ba5e ("Pass pitch from drmmode_crtc_scanout_allocate to drmmode_create_bo_pixmap") Reviewed-by: Alex Deucher --- src/drmmode_display.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index fd22a19b..560bfae4 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1194,14 +1194,20 @@ drmmode_show_cursor (xf86CrtcPtr crtc) info->cursor_w, info->cursor_h); } +/* Xorg expects a non-NULL return value from drmmode_crtc_shadow_allocate, and + * passes that back to drmmode_crtc_scanout_create; it doesn't use it for + * anything else. + */ static void * drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - int pitch; - return drmmode_crtc_scanout_allocate(crtc, &drmmode_crtc->rotate, - width, height, &pitch); + if (!drmmode_crtc_scanout_create(crtc, &drmmode_crtc->rotate, width, + height)) + return NULL; + + return (void*)~0UL; } static PixmapPtr @@ -1209,11 +1215,12 @@ drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - /* Xorg passes in the return value of drmmode_crtc_shadow_allocate - * for data, but that's redundant for drmmode_crtc_scanout_create. - */ - return drmmode_crtc_scanout_create(crtc, &drmmode_crtc->rotate, width, - height); + if (!data) { + drmmode_crtc_scanout_create(crtc, &drmmode_crtc->rotate, width, + height); + } + + return drmmode_crtc->rotate.pixmap; } static void -- cgit v1.2.3 From ae921a3150f69c38b5b3c88a9e37d54fdf0d5093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 28 Feb 2017 17:47:09 +0900 Subject: Fold drmmode_crtc_scanout_allocate into drmmode_crtc_scanout_create Not used anywhere else anymore. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 65 +++++++++++++++------------------------------------ 1 file changed, 19 insertions(+), 46 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 560bfae4..38b36b24 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -550,10 +550,9 @@ drmmode_scanout_free(ScrnInfoPtr scrn) drmmode_crtc_scanout_free(xf86_config->crtc[c]->driver_private); } -static void * -drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc, - struct drmmode_scanout *scanout, - int width, int height, int *pitch) +static PixmapPtr +drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, + int width, int height) { ScrnInfoPtr pScrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); @@ -561,11 +560,11 @@ drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc, drmmode_ptr drmmode = drmmode_crtc->drmmode; struct radeon_surface surface; uint32_t tiling = RADEON_CREATE_PIXMAP_TILING_MACRO; - int ret; + int pitch; - if (scanout->bo) { + if (scanout->pixmap) { if (scanout->width == width && scanout->height == height) - return scanout->bo->ptr; + return scanout->pixmap; drmmode_crtc_scanout_destroy(drmmode, scanout); } @@ -574,48 +573,16 @@ drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc, tiling |= RADEON_CREATE_PIXMAP_TILING_MICRO; scanout->bo = radeon_alloc_pixmap_bo(pScrn, width, height, pScrn->depth, tiling, pScrn->bitsPerPixel, - pitch, &surface, &tiling); + &pitch, &surface, &tiling); if (scanout->bo == NULL) - return NULL; - - radeon_bo_map(scanout->bo, 1); + goto error; - ret = drmModeAddFB(drmmode->fd, width, height, pScrn->depth, - pScrn->bitsPerPixel, *pitch, + if (drmModeAddFB(drmmode->fd, width, height, pScrn->depth, + pScrn->bitsPerPixel, pitch, scanout->bo->handle, - &scanout->fb_id); - if (ret) { + &scanout->fb_id) != 0) { ErrorF("failed to add scanout fb\n"); - radeon_bo_unref(scanout->bo); - scanout->bo = NULL; - return NULL; - } - - scanout->width = width; - scanout->height = height; - return scanout->bo->ptr; -} - -static PixmapPtr -drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, - int width, int height) -{ - ScrnInfoPtr pScrn = crtc->scrn; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - int pitch; - - if (scanout->pixmap) { - if (scanout->width == width && scanout->height == height) - return scanout->pixmap; - - drmmode_crtc_scanout_destroy(drmmode, scanout); - } - - if (!scanout->bo) { - if (!drmmode_crtc_scanout_allocate(crtc, scanout, width, height, - &pitch)) - return NULL; + goto error; } scanout->pixmap = drmmode_create_bo_pixmap(pScrn, @@ -623,9 +590,15 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, pScrn->depth, pScrn->bitsPerPixel, pitch, scanout->bo, NULL); - if (scanout->pixmap == NULL) + if (scanout->pixmap) { + scanout->width = width; + scanout->height = height; + } else { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't allocate scanout pixmap for CRTC\n"); +error: + drmmode_crtc_scanout_destroy(drmmode, scanout); + } return scanout->pixmap; } -- cgit v1.2.3 From f2bc882f1c1082bed9f496cfab6c8f07a76bc122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 28 Feb 2017 17:31:14 +0900 Subject: Handle rotation in the driver also with Xorg 1.12-1.18 We cannot use the HW cursor in that case, but in turn we get more efficient and less teary updates of rotated outputs. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 38b36b24..9c69b556 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -673,23 +673,20 @@ drmmode_crtc_update_tear_free(xf86CrtcPtr crtc) #if XF86_CRTC_VERSION >= 4 +#if XF86_CRTC_VERSION < 7 +#define XF86DriverTransformOutput TRUE +#define XF86DriverTransformNone FALSE +#endif + static Bool drmmode_handle_transform(xf86CrtcPtr crtc) { Bool ret; -#if XF86_CRTC_VERSION >= 7 if (crtc->transformPresent || crtc->rotation != RR_Rotate_0) crtc->driverIsPerformingTransform = XF86DriverTransformOutput; else crtc->driverIsPerformingTransform = XF86DriverTransformNone; -#else - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - RADEONInfoPtr info = RADEONPTR(crtc->scrn); - - crtc->driverIsPerformingTransform = crtc->transformPresent || - (drmmode_crtc->tear_free && crtc->rotation != RR_Rotate_0); -#endif ret = xf86CrtcRotate(crtc); -- cgit v1.2.3 From 9a951a3e551db58ba50e7a594521ceac54d90615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 28 Feb 2017 18:06:55 +0900 Subject: present: Also flush before using a flip to unflip Not doing so might result in intermittently scanning out stale contents of the screen pixmap. Reviewed-by: Alex Deucher --- src/radeon_present.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/radeon_present.c b/src/radeon_present.c index 1b0ddcb8..6409fe36 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -374,6 +374,8 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) int old_fb_id; int i; + radeon_cs_flush_indirect(scrn); + if (!radeon_present_check_unflip(scrn)) goto modeset; @@ -404,7 +406,6 @@ modeset: old_fb_id = info->drmmode.fb_id; info->drmmode.fb_id = 0; - radeon_cs_flush_indirect(scrn); radeon_bo_wait(info->front_bo); for (i = 0; i < config->num_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; -- cgit v1.2.3 From 0a4eb0e12f0c9c653cf4cea6fd62e1a507eb261c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 10 Feb 2017 12:52:02 +0900 Subject: present: Use async flip for unflip if possible In that case, unflip operations should finish faster in general. Reviewed-by: Alex Deucher --- src/radeon_present.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/radeon_present.c b/src/radeon_present.c index 6409fe36..01409ffa 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -48,6 +48,8 @@ #include "present.h" +static present_screen_info_rec radeon_present_screen_info; + struct radeon_present_vblank_event { uint64_t event_id; Bool unflip; @@ -370,6 +372,9 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); struct radeon_present_vblank_event *event; PixmapPtr pixmap = screen->GetScreenPixmap(screen); + enum drmmode_flip_sync flip_sync = + (radeon_present_screen_info.capabilities & PresentCapabilityAsync) ? + FLIP_ASYNC : FLIP_VSYNC; uint32_t handle; int old_fb_id; int i; @@ -396,7 +401,7 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) if (radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle, event_id, event, -1, radeon_present_flip_event, - radeon_present_flip_abort, FLIP_VSYNC, 0)) + radeon_present_flip_abort, flip_sync, 0)) return; modeset: -- cgit v1.2.3 From 9035b6abea557828e672ee455f0c84e43da0906f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 28 Feb 2017 18:13:42 +0900 Subject: present: Flush before flipping This isn't necessary for DRI clients, but the Present extension can also be used for presenting normal pixmaps rendered to via the X11 protocol. Reviewed-by: Alex Deucher --- src/radeon_present.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/radeon_present.c b/src/radeon_present.c index 01409ffa..af55e462 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -347,6 +347,8 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, event->event_id = event_id; + radeon_cs_flush_indirect(scrn); + ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle, event_id, event, crtc_id, radeon_present_flip_event, -- cgit v1.2.3 From df2d749a4db33298c8ce9f2cfb77c20c5538c9cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 2 Mar 2017 16:05:42 +0900 Subject: Fix bogus indentation Trivial. Fixes: 58cd1600057e ("Allow toggling TearFree at runtime via output property") --- src/drmmode_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 9c69b556..a7904a39 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -769,7 +769,7 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, #endif /* RADEON_PIXMAP_SHARING */ - static void +static void drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, unsigned scanout_id, int *fb_id, int *x, int *y) { -- cgit v1.2.3 From 0a12bf1085505017068dfdfd31d23133e51b45b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 1 Mar 2017 18:00:40 +0900 Subject: Call drmmode_set_desired_modes from a WindowExposures hook This is the earliest opportunity where the root window contents are guaranteed to be initialized, and prevents drmmode_set_mode_major from getting called before drmmode_set_desired_modes via RADEONUnblank -> drmmode_crtc_dpms. Also, in contrast to the BlockHandler hook, this is called when running Xorg with -pogo. Fixes intermittently showing garbage on server startup or after server reset. As a bonus, this avoids trouble due to higher layers (e.g. the tigervnc Xorg module) calling RADEONBlockHandler_oneshot repeatedly even after we set pScreen->BlockHandler = RADEONBlockHandler_KMS. v2: * Drop spaces between XORG_VERSION_NUMERIC arguments * Call radeon_bo_wait after radeon_cs_flush_indirect Bugzilla: https://bugs.freedesktop.org/99457 Reviewed-by: Alex Deucher (v1) --- src/radeon.h | 1 + src/radeon_kms.c | 41 +++++++++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/radeon.h b/src/radeon.h index bfff232c..815c12a1 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -523,6 +523,7 @@ typedef struct { CreateScreenResourcesProcPtr CreateScreenResources; CreateWindowProcPtr CreateWindow; + WindowExposuresProcPtr WindowExposures; Bool IsSecondary; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 331f3f1c..c2089eba 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1137,17 +1137,6 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) #endif } -static void RADEONBlockHandler_oneshot(BLOCKHANDLER_ARGS_DECL) -{ - SCREEN_PTR(arg); - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - RADEONInfoPtr info = RADEONPTR(pScrn); - - RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS); - - drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE); -} - static Bool RADEONIsFastFBWorking(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -1636,6 +1625,32 @@ static Bool RADEONCreateWindow_oneshot(WindowPtr pWin) return ret; } +/* When the root window is mapped, set the initial modes */ +static void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0) + , RegionPtr pBSRegion +#endif + ) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (pWin != pScreen->root) + ErrorF("%s called for non-root window %p\n", __func__, pWin); + + pScreen->WindowExposures = info->WindowExposures; +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0) + pScreen->WindowExposures(pWin, pRegion, RegionPtr pBSRegion); +#else + pScreen->WindowExposures(pWin, pRegion); +#endif + + radeon_cs_flush_indirect(pScrn); + radeon_bo_wait(info->front_bo); + drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE); +} + Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) { RADEONInfoPtr info; @@ -2330,6 +2345,8 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) info->CreateWindow = pScreen->CreateWindow; pScreen->CreateWindow = RADEONCreateWindow_oneshot; } + info->WindowExposures = pScreen->WindowExposures; + pScreen->WindowExposures = RADEONWindowExposures_oneshot; /* Provide SaveScreen & wrap BlockHandler and CloseScreen */ /* Wrap CloseScreen */ @@ -2337,7 +2354,7 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) pScreen->CloseScreen = RADEONCloseScreen_KMS; pScreen->SaveScreen = RADEONSaveScreen_KMS; info->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = RADEONBlockHandler_oneshot; + pScreen->BlockHandler = RADEONBlockHandler_KMS; info->CreateScreenResources = pScreen->CreateScreenResources; pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS; -- cgit v1.2.3 From cc9d6b7db9c2078be1e530a64af6d517c6a42024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 1 Mar 2017 17:35:59 +0900 Subject: Move DPMS check from radeon_scanout_do_update to radeon_scanout_flip When radeon_scanout_do_update is called from drmmode_crtc_scanout_update, drmmode_crtc->pending_dpms_mode may still be != DPMSModeOn, e.g. during server startup. Fixes intermittently showing garbage with TearFree enabled. --- src/radeon_kms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index c2089eba..572dfcc8 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -882,7 +882,6 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id) Bool force; if (!xf86_crtc->enabled || - drmmode_crtc->pending_dpms_mode != DPMSModeOn || !drmmode_crtc->scanout[scanout_id].pixmap) return FALSE; @@ -1069,7 +1068,8 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, uintptr_t drm_queue_seq; unsigned scanout_id; - if (drmmode_crtc->scanout_update_pending) + if (drmmode_crtc->scanout_update_pending || + drmmode_crtc->pending_dpms_mode != DPMSModeOn) return; scanout_id = drmmode_crtc->scanout_id ^ 1; -- cgit v1.2.3 From d63881623f0686a66a2e3e3c1f84e496aa52ec6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 2 Mar 2017 16:22:51 +0900 Subject: Don't call radeon_cs_flush_indirect & radeon_bo_wait in drmmode_copy_fb RADEONWindowExposures_oneshot takes care of it. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index a7904a39..ab11583a 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -490,9 +490,6 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) FreeScratchGC(gc); - radeon_cs_flush_indirect(pScrn); - radeon_bo_wait(info->front_bo); - pScreen->canDoBGNoneRoot = TRUE; destroy_pixmap_for_fbcon(pScrn); return; -- cgit v1.2.3 From f0e7948e1c0e984fc27f235f365639e9cf628291 Mon Sep 17 00:00:00 2001 From: Jochen Rollwagen Date: Sun, 5 Mar 2017 11:32:38 +0100 Subject: Fix build for XServer 1.13 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Latest git build stops with the error message radeon_kms.c: In function 'RADEONWindowExposures_oneshot': radeon_kms.c:1644:45: error: expected expression before 'RegionPtr' pScreen->WindowExposures(pWin, pRegion, RegionPtr pBSRegion); This patch fixes the build. Reviewed-by: Michel Dänzer --- src/radeon_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 572dfcc8..7a561faa 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1641,7 +1641,7 @@ static void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion pScreen->WindowExposures = info->WindowExposures; #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0) - pScreen->WindowExposures(pWin, pRegion, RegionPtr pBSRegion); + pScreen->WindowExposures(pWin, pRegion, pBSRegion); #else pScreen->WindowExposures(pWin, pRegion); #endif -- cgit v1.2.3 From 67ae5e00a748ad52cf92738d401afff2947b1891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 8 Mar 2017 11:20:30 +0900 Subject: Skip some initialization steps for GPU screens Xorg doesn't use the following functionality of GPU screens, so don't bother initializing it: * DRI page flipping * DRI3 / Present / SYNC fences * XVideo / XvMC * Root window with background None Reviewed-by: Alex Deucher --- src/radeon.h | 2 + src/radeon_kms.c | 111 ++++++++++++++++++++++++++++++------------------------- 2 files changed, 62 insertions(+), 51 deletions(-) diff --git a/src/radeon.h b/src/radeon.h index 815c12a1..73744115 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -183,8 +183,10 @@ typedef enum { #if XF86_CRTC_VERSION >= 5 #define RADEON_PIXMAP_SHARING 1 #define radeon_is_gpu_screen(screen) (screen)->isGPU +#define radeon_is_gpu_scrn(scrn) (scrn)->is_gpu #else #define radeon_is_gpu_screen(screen) 0 +#define radeon_is_gpu_scrn(scrn) 0 #endif #define RADEON_VSYNC_TIMEOUT 20000 /* Maximum wait for VSYNC (in usecs) */ diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 7a561faa..907ebfcf 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1811,32 +1811,36 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) info->tear_free == 2 ? "auto" : (info->tear_free ? "on" : "off")); } - if (info->dri2.pKernelDRMVersion->version_minor >= 8) { - Bool sw_cursor = xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE); - - info->allowPageFlip = xf86ReturnOptValBool(info->Options, - OPTION_PAGE_FLIP, TRUE); - - if (sw_cursor || info->shadow_primary) { - xf86DrvMsg(pScrn->scrnIndex, - info->allowPageFlip ? X_WARNING : X_DEFAULT, - "KMS Pageflipping: disabled%s\n", - info->allowPageFlip ? - (sw_cursor ? " because of SWcursor" : - " because of ShadowPrimary") : ""); - info->allowPageFlip = FALSE; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "KMS Pageflipping: %sabled\n", info->allowPageFlip ? "en" : "dis"); + if (!radeon_is_gpu_scrn(pScrn)) { + if (info->dri2.pKernelDRMVersion->version_minor >= 8) { + Bool sw_cursor = xf86ReturnOptValBool(info->Options, + OPTION_SW_CURSOR, FALSE); + + info->allowPageFlip = xf86ReturnOptValBool(info->Options, + OPTION_PAGE_FLIP, TRUE); + + if (sw_cursor || info->shadow_primary) { + xf86DrvMsg(pScrn->scrnIndex, + info->allowPageFlip ? X_WARNING : X_DEFAULT, + "KMS Pageflipping: disabled%s\n", + info->allowPageFlip ? + (sw_cursor ? " because of SWcursor" : + " because of ShadowPrimary") : ""); + info->allowPageFlip = FALSE; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "KMS Pageflipping: %sabled\n", + info->allowPageFlip ? "en" : "dis"); + } } - } - if (!info->use_glamor) { - info->swapBuffersWait = - xf86ReturnOptValBool(info->Options, OPTION_SWAPBUFFERS_WAIT, TRUE); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "SwapBuffers wait for vsync: %sabled\n", - info->swapBuffersWait ? "en" : "dis"); + if (!info->use_glamor) { + info->swapBuffersWait = + xf86ReturnOptValBool(info->Options, OPTION_SWAPBUFFERS_WAIT, TRUE); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SwapBuffers wait for vsync: %sabled\n", + info->swapBuffersWait ? "en" : "dis"); + } } if (xf86ReturnOptValBool(info->Options, OPTION_DELETE_DP12, FALSE)) { @@ -2244,33 +2248,35 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) } #endif - if (xorgGetVersion() >= XORG_VERSION_NUMERIC(1,18,3,0,0)) - value = info->use_glamor; - else - value = FALSE; - from = X_DEFAULT; + if (!radeon_is_gpu_screen(pScreen)) { + if (xorgGetVersion() >= XORG_VERSION_NUMERIC(1,18,3,0,0)) + value = info->use_glamor; + else + value = FALSE; + from = X_DEFAULT; - if (!info->r600_shadow_fb) { - if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value)) - from = X_CONFIG; + if (!info->r600_shadow_fb) { + if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value)) + from = X_CONFIG; - if (xf86GetOptValInteger(info->Options, OPTION_DRI, &driLevel) && - (driLevel == 2 || driLevel == 3)) { - from = X_CONFIG; - value = driLevel == 3; + if (xf86GetOptValInteger(info->Options, OPTION_DRI, &driLevel) && + (driLevel == 2 || driLevel == 3)) { + from = X_CONFIG; + value = driLevel == 3; + } } - } - if (value) { - value = radeon_sync_init(pScreen) && - radeon_present_screen_init(pScreen) && - radeon_dri3_screen_init(pScreen); + if (value) { + value = radeon_sync_init(pScreen) && + radeon_present_screen_init(pScreen) && + radeon_dri3_screen_init(pScreen); - if (!value) - from = X_WARNING; - } + if (!value) + from = X_WARNING; + } - xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %sabled\n", value ? "en" : "dis"); + xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %sabled\n", value ? "en" : "dis"); + } pScrn->vtSema = TRUE; xf86SetBackingStore(pScreen); @@ -2325,7 +2331,8 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) */ /* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */ #endif - if (info->r600_shadow_fb == FALSE) { + if (info->r600_shadow_fb == FALSE && + !radeon_is_gpu_screen(pScreen)) { /* Init Xv */ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "Initializing Xv\n"); @@ -2341,12 +2348,14 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) } pScrn->pScreen = pScreen; - if (serverGeneration == 1 && bgNoneRoot && info->accelOn) { - info->CreateWindow = pScreen->CreateWindow; - pScreen->CreateWindow = RADEONCreateWindow_oneshot; + if (!radeon_is_gpu_screen(pScreen)) { + if (serverGeneration == 1 && bgNoneRoot && info->accelOn) { + info->CreateWindow = pScreen->CreateWindow; + pScreen->CreateWindow = RADEONCreateWindow_oneshot; + } + info->WindowExposures = pScreen->WindowExposures; + pScreen->WindowExposures = RADEONWindowExposures_oneshot; } - info->WindowExposures = pScreen->WindowExposures; - pScreen->WindowExposures = RADEONWindowExposures_oneshot; /* Provide SaveScreen & wrap BlockHandler and CloseScreen */ /* Wrap CloseScreen */ -- cgit v1.2.3 From 9a71445094b728f3d78db8f6808b4782ee19a453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 8 Mar 2017 17:42:56 +0900 Subject: Pass TRUE to drmmode_set_desired_modes the first time for GPU screens This is the only place we call drmmode_set_desired_modes for GPU screens during server startup. Without this change, the display outputs of secondary GPUs may stay on even while Xorg isn't using them. Reviewed-by: Alex Deucher --- src/radeon_kms.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 907ebfcf..424f9f72 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -328,7 +328,8 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) } } - if (!drmmode_set_desired_modes(pScrn, &info->drmmode, FALSE)) + if (!drmmode_set_desired_modes(pScrn, &info->drmmode, + radeon_is_gpu_screen(pScreen))) return FALSE; drmmode_uevent_init(pScrn, &info->drmmode); -- cgit v1.2.3 From 66227060872219c1a0dc84fa4cea6264f7548446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 16 Mar 2017 16:38:15 +0900 Subject: Bump version for 7.9.0 release --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 732f7050..b83b18f3 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [7.8.99], + [7.9.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xf86-video-ati]) -- cgit v1.2.3 From dc30f5e27ef8a8e980adb21c1fea7c4f60c7e896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 23 Mar 2017 18:06:23 +0900 Subject: Post-release version bump --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b83b18f3..c9ccfb3d 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [7.9.0], + [7.9.99], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xf86-video-ati]) -- cgit v1.2.3 From 23985d3ef3150ef8cad30b92ef0cd8ba6cfa1f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 23 Mar 2017 18:06:45 +0900 Subject: manpage: Don't put "'" at the beginning of a line It caused the whole line to be dropped. Fixes: 58cd1600057e ("Allow toggling TearFree at runtime via output property") Reported-by: Andy Furniss Reviewed-by: Alex Deucher (amdgpu commit) (Ported from amdgpu commit 165b51447643ce37f391f25ca6aecb8d76fabaa3) --- man/radeon.man | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man/radeon.man b/man/radeon.man index 5301dd7f..9334d9e8 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -286,8 +286,8 @@ tearing prevention using the hardware page flipping mechanism. TearFree is on for any CRTC associated with one or more outputs with TearFree on. Two separate scanout buffers need to be allocated for each CRTC with TearFree on. While TearFree is on for any CRTC, it currently prevents clients from using -DRI page flipping. If this option is set, the default value of the property is -'on' or 'off' accordingly. If this option isn't set, the default value of the +DRI page flipping. If this option is set, the default value of the property +is 'on' or 'off' accordingly. If this option isn't set, the default value of the property is .B auto, which means that TearFree is on for outputs with rotation or other RandR -- cgit v1.2.3 From d6c29250dbc293c932ca14997eb23399610b106d Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Fri, 7 Apr 2017 14:27:58 +0100 Subject: Set correct DRM event context version DRM_EVENT_CONTEXT_VERSION is the latest context version supported by whatever version of libdrm is present. We were blindly asserting we supported whatever version that may be, even if we actually didn't. Set the version as 2, which should be bumped only with the appropriate version checks. Signed-off-by: Daniel Stone (Ported from xserver commit 0c8e6ed85810e96d84173a52d628863802a78d82) v2: Remove second paragraph of commit log, we always initialize page_flip_handler2 = NULL (Emil Velikov) Reviewed-by: Emil Velikov Reviewed-by: Alex Deucher # v1 --- src/drmmode_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index ab11583a..9911c0a6 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2538,7 +2538,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) xf86InitialConfiguration(pScrn, TRUE); - drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION; + drmmode->event_context.version = 2; drmmode->event_context.vblank_handler = radeon_drm_queue_handler; drmmode->event_context.page_flip_handler = radeon_drm_queue_handler; -- cgit v1.2.3 From 4c91f36d3058180b5a2d6a23e9b82f5c933d8716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 17 Apr 2017 18:32:31 +0900 Subject: Don't set modes before RADEONWindowExposures_oneshot is called The root window contents may be undefined before that, so we don't want to show anything yet. Fixes a crash on startup with rotation and virtual resolution set in xorg.conf. Bugzilla: https://bugs.freedesktop.org/100276 Fixes: cc9d6b7db9c2 ("Move DPMS check from radeon_scanout_do_update to radeon_scanout_flip") (Ported from amdgpu commit 981bac185cfd74ae50dffc28f57cf34623a9595f) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 6 ++++++ src/radeon.h | 5 +++++ src/radeon_kms.c | 6 +++--- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 9911c0a6..84e7ef96 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -833,6 +833,12 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, int fb_id; drmModeModeInfo kmode; + /* The root window contents may be undefined before the WindowExposures + * hook is called for it, so bail if we get here before that + */ + if (pScreen->WindowExposures == RADEONWindowExposures_oneshot) + return FALSE; + saved_mode = crtc->mode; saved_x = crtc->x; saved_y = crtc->y; diff --git a/src/radeon.h b/src/radeon.h index 73744115..2cb188e1 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -634,6 +634,11 @@ Bool radeon_dri3_screen_init(ScreenPtr screen); /* radeon_kms.c */ Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id); +void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0) + , RegionPtr pBSRegion +#endif + ); /* radeon_present.c */ Bool radeon_present_screen_init(ScreenPtr screen); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 424f9f72..b3427c46 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1627,11 +1627,11 @@ static Bool RADEONCreateWindow_oneshot(WindowPtr pWin) } /* When the root window is mapped, set the initial modes */ -static void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion +void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0) - , RegionPtr pBSRegion + , RegionPtr pBSRegion #endif - ) + ) { ScreenPtr pScreen = pWin->drawable.pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); -- cgit v1.2.3 From f32c45194ac6f82cbe42d255ed72f857018778e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 9 May 2017 11:18:00 +0900 Subject: Apply gamma correction to HW cursor The display hardware CLUT we're currently using for gamma correction doesn't affect the HW cursor, so we have to apply it manually when uploading the HW cursor data. This currently only works in depth 24/32. (Ported from amdgpu commit 82fa615f38137add75f9cd4bb49c48dd88de916f) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 66 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 84e7ef96..0b823754 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -812,6 +812,17 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, } } +static void +drmmode_crtc_gamma_do_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, + uint16_t *blue, int size) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + drmModeCrtcSetGamma(drmmode_crtc->drmmode->fd, + drmmode_crtc->mode_crtc->crtc_id, size, red, green, + blue); +} + static Bool drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y) @@ -873,8 +884,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, if (drmmode_crtc->tear_free) scanout_id = drmmode_crtc->scanout_id; - crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, - crtc->gamma_blue, crtc->gamma_size); + drmmode_crtc_gamma_do_set(crtc, crtc->gamma_red, crtc->gamma_green, + crtc->gamma_blue, crtc->gamma_size); drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); @@ -1043,6 +1054,31 @@ drmmode_cursor_src_offset(Rotation rotation, int width, int height, #endif +static uint32_t +drmmode_cursor_gamma(xf86CrtcPtr crtc, uint32_t argb) +{ + uint32_t alpha = argb >> 24; + uint32_t rgb[3]; + int i; + + if (!alpha) + return 0; + + if (crtc->scrn->depth != 24 && crtc->scrn->depth != 32) + return argb; + + /* Un-premultiply alpha */ + for (i = 0; i < 3; i++) + rgb[i] = ((argb >> (i * 8)) & 0xff) * 0xff / alpha; + + /* Apply gamma correction and pre-multiply alpha */ + rgb[0] = (crtc->gamma_blue[rgb[0]] >> 8) * alpha / 0xff; + rgb[1] = (crtc->gamma_green[rgb[1]] >> 8) * alpha / 0xff; + rgb[2] = (crtc->gamma_red[rgb[2]] >> 8) * alpha / 0xff; + + return alpha << 24 | rgb[2] << 16 | rgb[1] << 8 | rgb[0]; +} + static void drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) { @@ -1068,7 +1104,8 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) dstx, dsty); ptr[dsty * info->cursor_w + dstx] = - cpu_to_le32(image[srcoffset]); + cpu_to_le32(drmmode_cursor_gamma(crtc, + image[srcoffset])); } } } else @@ -1078,7 +1115,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) int i; for (i = 0; i < cursor_size; i++) - ptr[i] = cpu_to_le32(image[i]); + ptr[i] = cpu_to_le32(drmmode_cursor_gamma(crtc, image[i])); } } @@ -1209,11 +1246,24 @@ static void drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, uint16_t *blue, int size) { - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; + ScrnInfoPtr scrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + RADEONInfoPtr info = RADEONPTR(scrn); + int i; - drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, - size, red, green, blue); + drmmode_crtc_gamma_do_set(crtc, red, green, blue, size); + + /* Compute index of this CRTC into xf86_config->crtc */ + for (i = 0; xf86_config->crtc[i] != crtc; i++) {} + + if (info->hwcursor_disabled & (1 << i)) + return; + +#ifdef HAVE_XF86_CURSOR_RESET_CURSOR + xf86CursorResetCursor(scrn->pScreen); +#else + xf86_reload_cursors(scrn->pScreen); +#endif } #ifdef RADEON_PIXMAP_SHARING -- cgit v1.2.3 From 944391b0052466b71bf9919b56139dc197a7e072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 8 Feb 2017 18:14:30 +0900 Subject: Pass pixmap instead of handle to radeon_do_pageflip This brings us in line with amdgpu and prepares for the following change, no functional change intended. (Ported from amdgpu commit e463b849f3e9d7b69e64a65619a22e00e78d297b) v2: * Be more consistent with the amdgpu code, which should make porting the following change to amdgpu easier Reviewed-by: Alex Deucher --- src/drmmode_display.c | 26 +++++++++----------------- src/drmmode_display.h | 2 +- src/radeon_dri2.c | 5 +---- src/radeon_present.c | 15 ++------------- 4 files changed, 13 insertions(+), 35 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 0b823754..a101ac23 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2950,36 +2950,27 @@ void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode) } Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, - uint32_t new_front_handle, uint64_t id, void *data, + PixmapPtr new_front, uint64_t id, void *data, int ref_crtc_hw_id, radeon_drm_handler_proc handler, radeon_drm_abort_proc abort, enum drmmode_flip_sync flip_sync, uint32_t target_msc) { RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - RADEONInfoPtr info = RADEONPTR(scrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcPtr crtc = NULL; drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; - unsigned int pitch; int i; - uint32_t tiling_flags = 0; uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0; drmmode_flipdata_ptr flipdata; uintptr_t drm_queue_seq = 0; + uint32_t new_front_handle; - if (info->allowColorTiling) { - if (info->ChipFamily >= CHIP_FAMILY_R600) - tiling_flags |= RADEON_TILING_MICRO; - else - tiling_flags |= RADEON_TILING_MACRO; - } - - pitch = RADEON_ALIGN(scrn->displayWidth, drmmode_get_pitch_align(scrn, info->pixel_bytes, tiling_flags)) * - info->pixel_bytes; - if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) { - pitch = info->front_surface.level[0].pitch_bytes; + if (!radeon_get_pixmap_handle(new_front, &new_front_handle)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "flip queue: failed to get new front handle\n"); + return FALSE; } flipdata = calloc(1, sizeof(drmmode_flipdata_rec)); @@ -2993,8 +2984,9 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, * Create a new handle for the back buffer */ flipdata->old_fb_id = drmmode->fb_id; - if (drmModeAddFB(drmmode->fd, scrn->virtualX, scrn->virtualY, - scrn->depth, scrn->bitsPerPixel, pitch, + if (drmModeAddFB(drmmode->fd, new_front->drawable.width, + new_front->drawable.height, scrn->depth, + scrn->bitsPerPixel, new_front->devKind, new_front_handle, &drmmode->fb_id)) goto error; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index bd3f5f98..35d64179 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -168,7 +168,7 @@ extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); extern void drmmode_clear_pending_flip(xf86CrtcPtr crtc); Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, - uint32_t new_front_handle, uint64_t id, void *data, + PixmapPtr new_front, uint64_t id, void *data, int ref_crtc_hw_id, radeon_drm_handler_proc handler, radeon_drm_abort_proc abort, enum drmmode_flip_sync flip_sync, diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index c108ceab..cc72bd52 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -652,7 +652,6 @@ radeon_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client, ScrnInfoPtr scrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(scrn); struct dri2_buffer_priv *back_priv; - struct radeon_bo *bo; DRI2FrameEventPtr flip_info; int ref_crtc_hw_id = drmmode_get_crtc_id(crtc); @@ -673,9 +672,7 @@ radeon_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client, /* Page flip the full screen buffer */ back_priv = back->driverPrivate; - bo = radeon_get_pixmap_bo(back_priv->pixmap); - - if (radeon_do_pageflip(scrn, client, bo->handle, + if (radeon_do_pageflip(scrn, client, back_priv->pixmap, RADEON_DRM_QUEUE_ID_DEFAULT, flip_info, ref_crtc_hw_id, radeon_dri2_flip_event_handler, diff --git a/src/radeon_present.c b/src/radeon_present.c index af55e462..90632d0e 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -332,15 +332,11 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, struct radeon_present_vblank_event *event; xf86CrtcPtr xf86_crtc = crtc->devPrivate; int crtc_id = xf86_crtc ? drmmode_get_crtc_id(xf86_crtc) : -1; - uint32_t handle; Bool ret; if (!radeon_present_check_flip(crtc, screen->root, pixmap, sync_flip)) return FALSE; - if (!radeon_get_pixmap_handle(pixmap, &handle)) - return FALSE; - event = calloc(1, sizeof(struct radeon_present_vblank_event)); if (!event) return FALSE; @@ -349,7 +345,7 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, radeon_cs_flush_indirect(scrn); - ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle, + ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, pixmap, event_id, event, crtc_id, radeon_present_flip_event, radeon_present_flip_abort, @@ -377,7 +373,6 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) enum drmmode_flip_sync flip_sync = (radeon_present_screen_info.capabilities & PresentCapabilityAsync) ? FLIP_ASYNC : FLIP_VSYNC; - uint32_t handle; int old_fb_id; int i; @@ -386,12 +381,6 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) if (!radeon_present_check_unflip(scrn)) goto modeset; - if (!radeon_get_pixmap_handle(pixmap, &handle)) { - ErrorF("%s: radeon_get_pixmap_handle failed, display might freeze\n", - __func__); - goto modeset; - } - event = calloc(1, sizeof(struct radeon_present_vblank_event)); if (!event) { ErrorF("%s: calloc failed, display might freeze\n", __func__); @@ -401,7 +390,7 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) event->event_id = event_id; event->unflip = TRUE; - if (radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle, + if (radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, pixmap, event_id, event, -1, radeon_present_flip_event, radeon_present_flip_abort, flip_sync, 0)) return; -- cgit v1.2.3 From 55e513b978b2afc52b7cafc5bfcb0d1dc78d75f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Sat, 29 Apr 2017 17:05:58 +0900 Subject: Use reference counting for tracking KMS framebuffer lifetimes References are held by the pixmaps corresponding to the FBs (so the same KMS FB can be reused as long as the pixmap exists) and by the CRTCs scanning out from them (so a KMS FB is only destroyed once it's not being scanned out anymore, preventing intermittent black screens and worse issues due to a CRTC turning off when it should be on). v2: * Only increase reference count in drmmode_fb_reference if it was sane before * Make drmmode_fb_reference's indentation match the rest of drmmode_display.h Reviewed-by: Alex Deucher --- src/drmmode_display.c | 147 +++++++++++++++++++++---------------------------- src/drmmode_display.h | 39 +++++++++++-- src/radeon.h | 73 ++++++++++++++++++++++++ src/radeon_bo_helper.h | 3 - src/radeon_exa.c | 2 + src/radeon_kms.c | 64 ++++++++++++++++++--- src/radeon_present.c | 8 --- 7 files changed, 226 insertions(+), 110 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index a101ac23..ec307262 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -375,6 +375,7 @@ drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 0, 0, NULL, 0, NULL); + drmmode_fb_reference(drmmode->fd, &drmmode_crtc->fb, NULL); } else if (drmmode_crtc->dpms_mode != DPMSModeOn) crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); @@ -447,8 +448,9 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); - PixmapPtr src, dst; ScreenPtr pScreen = pScrn->pScreen; + PixmapPtr src, dst = pScreen->GetScreenPixmap(pScreen); + struct drmmode_fb *fb = radeon_pixmap_get_fb(dst); int fbcon_id = 0; Bool force; GCPtr gc; @@ -464,7 +466,7 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) if (!fbcon_id) return; - if (fbcon_id == drmmode->fb_id) { + if (fbcon_id == fb->handle) { /* 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 @@ -477,8 +479,6 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) if (!src) return; - dst = pScreen->GetScreenPixmap(pScreen); - gc = GetScratchGC(pScrn->depth, pScreen); ValidateGC(&dst->drawable, gc); @@ -505,8 +505,6 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, } if (scanout->bo) { - drmModeRmFB(drmmode->fd, scanout->fb_id); - scanout->fb_id = 0; radeon_bo_unmap(scanout->bo); radeon_bo_unref(scanout->bo); scanout->bo = NULL; @@ -571,15 +569,9 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, scanout->bo = radeon_alloc_pixmap_bo(pScrn, width, height, pScrn->depth, tiling, pScrn->bitsPerPixel, &pitch, &surface, &tiling); - if (scanout->bo == NULL) - goto error; - - if (drmModeAddFB(drmmode->fd, width, height, pScrn->depth, - pScrn->bitsPerPixel, pitch, - scanout->bo->handle, - &scanout->fb_id) != 0) { - ErrorF("failed to add scanout fb\n"); - goto error; + if (!scanout->bo) { + ErrorF("failed to create CRTC scanout BO\n"); + return NULL; } scanout->pixmap = drmmode_create_bo_pixmap(pScrn, @@ -587,13 +579,17 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, pScrn->depth, pScrn->bitsPerPixel, pitch, scanout->bo, NULL); - if (scanout->pixmap) { + if (!scanout->pixmap) { + ErrorF("failed to create CRTC scanout pixmap\n"); + goto error; + } + + if (radeon_pixmap_get_fb(scanout->pixmap)) { scanout->width = width; scanout->height = height; } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't allocate scanout pixmap for CRTC\n"); -error: + ErrorF("failed to create CRTC scanout FB\n"); +error: drmmode_crtc_scanout_destroy(drmmode, scanout); } @@ -706,8 +702,8 @@ drmmode_handle_transform(xf86CrtcPtr crtc) static void drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, - unsigned scanout_id, int *fb_id, int *x, - int *y) + unsigned scanout_id, struct drmmode_fb **fb, + int *x, int *y) { ScrnInfoPtr scrn = crtc->scrn; ScreenPtr screen = scrn->pScreen; @@ -759,7 +755,7 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, } } - *fb_id = drmmode_crtc->scanout[scanout_id].fb_id; + *fb = radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); *x = *y = 0; drmmode_crtc->scanout_id = scanout_id; } @@ -768,7 +764,8 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, static void drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, - unsigned scanout_id, int *fb_id, int *x, int *y) + unsigned scanout_id, struct drmmode_fb **fb, int *x, + int *y) { ScrnInfoPtr scrn = crtc->scrn; ScreenPtr screen = scrn->pScreen; @@ -804,7 +801,7 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, box->x2 = max(box->x2, scrn->virtualX); box->y2 = max(box->y2, scrn->virtualY); - *fb_id = drmmode_crtc->scanout[scanout_id].fb_id; + *fb = radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); *x = *y = 0; radeon_scanout_do_update(crtc, scanout_id); @@ -841,7 +838,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, int output_count = 0; Bool ret = FALSE; int i; - int fb_id; + struct drmmode_fb *fb = NULL; drmModeModeInfo kmode; /* The root window contents may be undefined before the WindowExposures @@ -889,15 +886,14 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); - fb_id = drmmode->fb_id; #ifdef RADEON_PIXMAP_SHARING if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) { drmmode_crtc_prime_scanout_update(crtc, mode, scanout_id, - &fb_id, &x, &y); + &fb, &x, &y); } else #endif - if (drmmode_crtc->rotate.fb_id) { - fb_id = drmmode_crtc->rotate.fb_id; + if (drmmode_crtc->rotate.pixmap) { + fb = radeon_pixmap_get_fb(drmmode_crtc->rotate.pixmap); x = y = 0; } else if (!radeon_is_gpu_screen(pScreen) && @@ -907,22 +903,24 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, #endif info->shadow_primary)) { drmmode_crtc_scanout_update(crtc, mode, scanout_id, - &fb_id, &x, &y); + &fb, &x, &y); } - if (fb_id == 0) { - if (drmModeAddFB(drmmode->fd, - pScrn->virtualX, - pScrn->virtualY, - pScrn->depth, pScrn->bitsPerPixel, - pScrn->displayWidth * info->pixel_bytes, - info->front_bo->handle, - &drmmode->fb_id) < 0) { - ErrorF("failed to add fb\n"); - goto done; - } - - fb_id = drmmode->fb_id; + if (!fb) + fb = radeon_pixmap_get_fb(pScreen->GetWindowPixmap(pScreen->root)); + if (!fb) { + fb = radeon_fb_create(drmmode->fd, pScrn->virtualX, + pScrn->virtualY, pScrn->depth, + pScrn->bitsPerPixel, + pScrn->displayWidth * info->pixel_bytes, + info->front_bo->handle); + /* Prevent refcnt of ad-hoc FBs from reaching 2 */ + drmmode_fb_reference(drmmode->fd, &drmmode_crtc->fb, NULL); + drmmode_crtc->fb = fb; + } + if (!fb) { + ErrorF("failed to add FB for modeset\n"); + goto done; } /* Wait for any pending flip to finish */ @@ -932,13 +930,15 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, if (drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, - fb_id, x, y, output_ids, + fb->handle, x, y, output_ids, output_count, &kmode) != 0) { xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "failed to set mode: %s\n", strerror(errno)); goto done; - } else + } else { ret = TRUE; + drmmode_fb_reference(drmmode->fd, &drmmode_crtc->fb, fb); + } if (pScreen) xf86CrtcSetScreenSubpixelOrder(pScreen); @@ -983,7 +983,9 @@ done: } else { crtc->active = TRUE; - if (fb_id != drmmode_crtc->scanout[scanout_id].fb_id) + if (drmmode_crtc->scanout[scanout_id].pixmap && + fb != radeon_pixmap_get_fb(drmmode_crtc-> + scanout[scanout_id].pixmap)) drmmode_crtc_scanout_free(drmmode_crtc); else if (!drmmode_crtc->tear_free) { drmmode_crtc_scanout_destroy(drmmode, @@ -2157,13 +2159,9 @@ static Bool drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - drmmode_crtc_private_ptr - drmmode_crtc = xf86_config->crtc[0]->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; RADEONInfoPtr info = RADEONPTR(scrn); struct radeon_bo *old_front = NULL; ScreenPtr screen = xf86ScrnToScreen(scrn); - uint32_t old_fb_id; int i, pitch, old_width, old_height, old_pitch; int aligned_height; uint32_t screen_size; @@ -2263,8 +2261,6 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) old_width = scrn->virtualX; old_height = scrn->virtualY; old_pitch = scrn->displayWidth; - old_fb_id = drmmode->fb_id; - drmmode->fb_id = 0; old_front = info->front_bo; scrn->virtualX = width; @@ -2346,8 +2342,6 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) crtc->rotation, crtc->x, crtc->y); } - if (old_fb_id) - drmModeRmFB(drmmode->fd, old_fb_id); if (old_front) radeon_bo_unref(old_front); @@ -2361,7 +2355,6 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) scrn->virtualX = old_width; scrn->virtualY = old_height; scrn->displayWidth = old_pitch; - drmmode->fb_id = old_fb_id; return FALSE; } @@ -2375,7 +2368,7 @@ drmmode_clear_pending_flip(xf86CrtcPtr crtc) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_crtc->flip_pending = FALSE; + drmmode_crtc->flip_pending = NULL; if (!crtc->enabled || (drmmode_crtc->pending_dpms_mode != DPMSModeOn && @@ -2419,7 +2412,7 @@ drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data) static void drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) { - RADEONInfoPtr info = RADEONPTR(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_flipdata_ptr flipdata = event_data; /* Is this the event whose info shall be delivered to higher level? */ @@ -2439,12 +2432,11 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even else flipdata->handler(crtc, frame, usec, flipdata->event_data); - /* Release framebuffer */ - drmModeRmFB(info->drmmode.fd, flipdata->old_fb_id); - free(flipdata); } + drmmode_fb_reference(drmmode_crtc->drmmode->fd, &drmmode_crtc->fb, + drmmode_crtc->flip_pending); drmmode_clear_pending_flip(crtc); } @@ -2701,6 +2693,8 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 0, 0, NULL, 0, NULL); + drmmode_fb_reference(drmmode->fd, + &drmmode_crtc->fb, NULL); } continue; } @@ -2960,18 +2954,11 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcPtr crtc = NULL; drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; int i; uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0; drmmode_flipdata_ptr flipdata; uintptr_t drm_queue_seq = 0; - uint32_t new_front_handle; - - if (!radeon_get_pixmap_handle(new_front, &new_front_handle)) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "flip queue: failed to get new front handle\n"); - return FALSE; - } + struct drmmode_fb *fb; flipdata = calloc(1, sizeof(drmmode_flipdata_rec)); if (!flipdata) { @@ -2980,15 +2967,11 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, goto error; } - /* - * Create a new handle for the back buffer - */ - flipdata->old_fb_id = drmmode->fb_id; - if (drmModeAddFB(drmmode->fd, new_front->drawable.width, - new_front->drawable.height, scrn->depth, - scrn->bitsPerPixel, new_front->devKind, - new_front_handle, &drmmode->fb_id)) + fb = radeon_pixmap_get_fb(new_front); + if (!fb) { + ErrorF("Failed to get FB for flip\n"); goto error; + } /* * Queue flips on all enabled CRTCs @@ -3032,7 +3015,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, if (drmmode_crtc->hw_id == ref_crtc_hw_id) { if (drmmode_page_flip_target_absolute(pRADEONEnt, drmmode_crtc, - drmmode->fb_id, + fb->handle, flip_flags, drm_queue_seq, target_msc) != 0) @@ -3040,13 +3023,13 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, } else { if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, - drmmode->fb_id, + fb->handle, flip_flags, drm_queue_seq, 0) != 0) goto flip_error; } - drmmode_crtc->flip_pending = TRUE; + drmmode_crtc->flip_pending = fb; drm_queue_seq = 0; } @@ -3058,12 +3041,6 @@ flip_error: strerror(errno)); error: - if (flipdata && flipdata->flip_count <= 1 && - drmmode->fb_id != flipdata->old_fb_id) { - drmModeRmFB(drmmode->fd, drmmode->fb_id); - drmmode->fb_id = flipdata->old_fb_id; - } - if (drm_queue_seq) radeon_drm_abort_entry(drm_queue_seq); else if (crtc) diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 35d64179..14d1cb03 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -41,7 +41,6 @@ typedef struct { int fd; - unsigned fb_id; drmModeFBPtr mode_fb; int cpp; struct radeon_bo_manager *bufmgr; @@ -60,7 +59,6 @@ typedef struct { } drmmode_rec, *drmmode_ptr; typedef struct { - unsigned old_fb_id; int flip_count; void *event_data; unsigned int fe_frame; @@ -70,10 +68,14 @@ typedef struct { radeon_drm_abort_proc abort; } drmmode_flipdata_rec, *drmmode_flipdata_ptr; +struct drmmode_fb { + int refcnt; + uint32_t handle; +}; + struct drmmode_scanout { struct radeon_bo *bo; PixmapPtr pixmap; - unsigned fb_id; int width, height; }; @@ -102,8 +104,10 @@ typedef struct { * modeset) */ Bool need_modeset; - /* A flip is pending for this CRTC */ - Bool flip_pending; + /* A flip to this FB is pending for this CRTC */ + struct drmmode_fb *flip_pending; + /* The FB currently being scanned out by this CRTC, if any */ + struct drmmode_fb *fb; } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; typedef struct { @@ -135,6 +139,31 @@ enum drmmode_flip_sync { }; +static inline void +drmmode_fb_reference(int drm_fd, struct drmmode_fb **old, struct drmmode_fb *new) +{ + if (new) { + if (new->refcnt <= 0) + ErrorF("New FB's refcnt was %d in %s\n", new->refcnt, __func__); + else + new->refcnt++; + } + + if (*old) { + if ((*old)->refcnt <= 0) { + ErrorF("Old FB's refcnt was %d in %s\n", (*old)->refcnt, __func__); + } else { + if (--(*old)->refcnt == 0) { + drmModeRmFB(drm_fd, (*old)->handle); + free(*old); + } + } + } + + *old = new; +} + + extern int drmmode_page_flip_target_absolute(RADEONEntPtr pRADEONEnt, drmmode_crtc_private_ptr drmmode_crtc, int fb_id, uint32_t flags, diff --git a/src/radeon.h b/src/radeon.h index 2cb188e1..febe580b 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -288,6 +288,7 @@ struct radeon_pixmap { uint_fast32_t gpu_write; struct radeon_bo *bo; + struct drmmode_fb *fb; uint32_t tiling_flags; @@ -313,6 +314,7 @@ static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pix struct radeon_exa_pixmap_priv { struct radeon_bo *bo; + struct drmmode_fb *fb; uint32_t tiling_flags; struct radeon_surface surface; Bool bo_mapped; @@ -609,6 +611,9 @@ extern void RADEONCopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int s extern void RADEONInit3DEngine(ScrnInfoPtr pScrn); extern int radeon_cs_space_remaining(ScrnInfoPtr pScrn); +/* radeon_bo_helper.c */ +extern Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle); + /* radeon_commonfuncs.c */ extern void RADEONWaitForVLine(ScrnInfoPtr pScrn, PixmapPtr pPix, xf86CrtcPtr crtc, int start, int stop); @@ -706,6 +711,8 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) radeon_bo_unref(priv->bo); } + drmmode_fb_reference(info->drmmode.fd, &priv->fb, NULL); + if (!bo) { free(priv); priv = NULL; @@ -790,6 +797,72 @@ static inline Bool radeon_get_pixmap_shared(PixmapPtr pPix) return FALSE; } +static inline struct drmmode_fb* +radeon_fb_create(int drm_fd, uint32_t width, uint32_t height, uint8_t depth, + uint8_t bpp, uint32_t pitch, uint32_t handle) +{ + struct drmmode_fb *fb = malloc(sizeof(*fb)); + + if (!fb) + return NULL; + + fb->refcnt = 1; + if (drmModeAddFB(drm_fd, width, height, depth, bpp, pitch, handle, + &fb->handle) == 0) + return fb; + + free(fb); + return NULL; +} + +static inline struct drmmode_fb* +radeon_pixmap_create_fb(int drm_fd, PixmapPtr pix) +{ + uint32_t handle; + + if (!radeon_get_pixmap_handle(pix, &handle)) + return NULL; + + return radeon_fb_create(drm_fd, pix->drawable.width, pix->drawable.height, + pix->drawable.depth, pix->drawable.bitsPerPixel, + pix->devKind, handle); +} + +static inline struct drmmode_fb* +radeon_pixmap_get_fb(PixmapPtr pix) +{ + RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pix->drawable.pScreen)); + +#ifdef USE_GLAMOR + if (info->use_glamor) { + struct radeon_pixmap *priv = radeon_get_pixmap_private(pix); + + if (!priv) + return NULL; + + if (!priv->fb) + priv->fb = radeon_pixmap_create_fb(info->drmmode.fd, pix); + + return priv->fb; + } else +#endif + if (info->accelOn) + { + struct radeon_exa_pixmap_priv *driver_priv = + exaGetPixmapDriverPrivate(pix); + + if (!driver_priv) + return NULL; + + if (!driver_priv->fb) + driver_priv->fb = radeon_pixmap_create_fb(info->drmmode.fd, pix); + + return driver_priv->fb; + } + + return NULL; +} + #define CP_PACKET0(reg, n) \ (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) #define CP_PACKET1(reg0, reg1) \ diff --git a/src/radeon_bo_helper.h b/src/radeon_bo_helper.h index f1aed551..77134250 100644 --- a/src/radeon_bo_helper.h +++ b/src/radeon_bo_helper.h @@ -28,9 +28,6 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, int usage_hint, int bitsPerPixel, int *new_pitch, struct radeon_surface *new_surface, uint32_t *new_tiling); -extern Bool -radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle); - extern uint32_t radeon_get_pixmap_tiling_flags(PixmapPtr pPix); diff --git a/src/radeon_exa.c b/src/radeon_exa.c index 1e457a8b..d8dd7fdc 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -300,6 +300,7 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv) { + RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pScreen)); struct radeon_exa_pixmap_priv *driver_priv = driverPriv; if (!driverPriv) @@ -307,6 +308,7 @@ void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv) if (driver_priv->bo) radeon_bo_unref(driver_priv->bo); + drmmode_fb_reference(info->drmmode.fd, &driver_priv->fb, NULL); free(driverPriv); } diff --git a/src/radeon_kms.c b/src/radeon_kms.c index b3427c46..2b410eb3 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -771,6 +771,17 @@ radeon_prime_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data) drmmode_clear_pending_flip(crtc); } +static void +radeon_prime_scanout_flip_handler(xf86CrtcPtr crtc, uint32_t msc, uint64_t usec, + void *event_data) +{ + drmmode_crtc_private_ptr drmmode_crtc = event_data; + + drmmode_fb_reference(drmmode_crtc->drmmode->fd, &drmmode_crtc->fb, + drmmode_crtc->flip_pending); + radeon_prime_scanout_flip_abort(crtc, event_data); +} + static void radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) { @@ -798,7 +809,8 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) drm_queue_seq = radeon_drm_queue_alloc(crtc, RADEON_DRM_QUEUE_CLIENT_DEFAULT, RADEON_DRM_QUEUE_ID_DEFAULT, - drmmode_crtc, NULL, + drmmode_crtc, + radeon_prime_scanout_flip_handler, radeon_prime_scanout_flip_abort); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -806,8 +818,17 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) return; } + drmmode_crtc->flip_pending = + radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); + if (!drmmode_crtc->flip_pending) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "Failed to get FB for PRIME flip.\n"); + radeon_drm_abort_entry(drm_queue_seq); + return; + } + if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, - drmmode_crtc->scanout[scanout_id].fb_id, + drmmode_crtc->flip_pending->handle, 0, drm_queue_seq, 0) != 0) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n", __func__, strerror(errno)); @@ -817,7 +838,6 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) drmmode_crtc->scanout_id = scanout_id; drmmode_crtc->scanout_update_pending = TRUE; - drmmode_crtc->flip_pending = TRUE; } static void @@ -1053,10 +1073,14 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) static void radeon_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data) { - drmmode_crtc_private_ptr drmmode_crtc = event_data; + radeon_prime_scanout_flip_abort(crtc, event_data); +} - drmmode_crtc->scanout_update_pending = FALSE; - drmmode_clear_pending_flip(crtc); +static void +radeon_scanout_flip_handler(xf86CrtcPtr crtc, uint32_t msc, uint64_t usec, + void *event_data) +{ + radeon_prime_scanout_flip_handler(crtc, msc, usec, event_data); } static void @@ -1080,7 +1104,8 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, RADEON_DRM_QUEUE_CLIENT_DEFAULT, RADEON_DRM_QUEUE_ID_DEFAULT, - drmmode_crtc, NULL, + drmmode_crtc, + radeon_scanout_flip_handler, radeon_scanout_flip_abort); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -1088,8 +1113,17 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, return; } + drmmode_crtc->flip_pending = + radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); + if (!drmmode_crtc->flip_pending) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "Failed to get FB for scanout flip.\n"); + radeon_drm_abort_entry(drm_queue_seq); + return; + } + if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, - drmmode_crtc->scanout[scanout_id].fb_id, + drmmode_crtc->flip_pending->handle, 0, drm_queue_seq, 0) != 0) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n", __func__, strerror(errno)); @@ -1099,7 +1133,6 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, drmmode_crtc->scanout_id = scanout_id; drmmode_crtc->scanout_update_pending = TRUE; - drmmode_crtc->flip_pending = TRUE; } static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) @@ -1114,6 +1147,19 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); pScreen->BlockHandler = RADEONBlockHandler_KMS; + if (!pScrn->vtSema) { + radeon_cs_flush_indirect(pScrn); + + for (c = 0; c < xf86_config->num_crtc; c++) { + drmmode_crtc_private_ptr drmmode_crtc = + xf86_config->crtc[c]->driver_private; + + drmmode_fb_reference(info->drmmode.fd, &drmmode_crtc->fb, NULL); + } + + return; + } + if (!radeon_is_gpu_screen(pScreen)) { for (c = 0; c < xf86_config->num_crtc; c++) { diff --git a/src/radeon_present.c b/src/radeon_present.c index 90632d0e..635d1086 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -373,7 +373,6 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) enum drmmode_flip_sync flip_sync = (radeon_present_screen_info.capabilities & PresentCapabilityAsync) ? FLIP_ASYNC : FLIP_VSYNC; - int old_fb_id; int i; radeon_cs_flush_indirect(scrn); @@ -396,12 +395,6 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) return; modeset: - /* info->drmmode.fb_id still points to the FB for the last flipped BO. - * Clear it, drmmode_set_mode_major will re-create it - */ - old_fb_id = info->drmmode.fb_id; - info->drmmode.fb_id = 0; - radeon_bo_wait(info->front_bo); for (i = 0; i < config->num_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; @@ -417,7 +410,6 @@ modeset: drmmode_crtc->need_modeset = TRUE; } - drmModeRmFB(info->drmmode.fd, old_fb_id); present_event_notify(event_id, 0, 0); info->drmmode.present_flipping = FALSE; -- cgit v1.2.3 From 7dc68e26755466f9056f8c72195ab8690660693d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 2 May 2017 11:47:58 +0900 Subject: Simplify tracking of PRIME scanout pixmap Remember the shared pixmap passed to drmmode_set_scanout_pixmap for each CRTC, and just compare against that. Fixes leaving stale entries in ScreenRec::pixmap_dirty_list under some circumstances, which would usually result in use-after-free and a crash down the line. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 21 +++++++++++---------- src/drmmode_display.h | 3 +++ src/radeon_kms.c | 7 ++----- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index ec307262..e2899cf5 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -732,9 +732,7 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { - if (dirty->src == crtc->randr_crtc->scanout_pixmap && - dirty->slave_dst == - drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap) { + if (dirty->src == drmmode_crtc->prime_scanout_pixmap) { dirty->slave_dst = drmmode_crtc->scanout[scanout_id].pixmap; break; @@ -887,7 +885,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); #ifdef RADEON_PIXMAP_SHARING - if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) { + if (drmmode_crtc->prime_scanout_pixmap) { drmmode_crtc_prime_scanout_update(crtc, mode, scanout_id, &fb, &x, &y); } else @@ -1278,14 +1276,15 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) PixmapDirtyUpdatePtr dirty; xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { - if (dirty->slave_dst != drmmode_crtc->scanout[scanout_id].pixmap) - continue; - - PixmapStopDirtyTracking(dirty->src, dirty->slave_dst); - drmmode_crtc_scanout_free(drmmode_crtc); - break; + if (dirty->src == drmmode_crtc->prime_scanout_pixmap) { + PixmapStopDirtyTracking(dirty->src, dirty->slave_dst); + break; + } } + drmmode_crtc_scanout_free(drmmode_crtc); + drmmode_crtc->prime_scanout_pixmap = NULL; + if (!ppix) return TRUE; @@ -1302,6 +1301,8 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) return FALSE; } + drmmode_crtc->prime_scanout_pixmap = ppix; + #ifdef HAS_DIRTYTRACKING_ROTATION PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[scanout_id].pixmap, 0, 0, 0, 0, RR_Rotate_0); diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 14d1cb03..df2c4b7b 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -92,6 +92,9 @@ typedef struct { unsigned scanout_id; Bool scanout_update_pending; Bool tear_free; + + PixmapPtr prime_scanout_pixmap; + int dpms_mode; /* For when a flip is pending when DPMS off requested */ int pending_dpms_mode; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 2b410eb3..c4bdfcfa 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -657,8 +657,7 @@ radeon_prime_dirty_to_crtc(PixmapDirtyUpdatePtr dirty) xf86CrtcPtr xf86_crtc = xf86_config->crtc[c]; drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; - if (drmmode_crtc->scanout[0].pixmap == dirty->slave_dst || - drmmode_crtc->scanout[1].pixmap == dirty->slave_dst) + if (drmmode_crtc->prime_scanout_pixmap == dirty->src) return xf86_crtc; } @@ -671,13 +670,11 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id) ScrnInfoPtr scrn = crtc->scrn; ScreenPtr screen = scrn->pScreen; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap; PixmapDirtyUpdatePtr dirty; Bool ret = FALSE; xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { - if (dirty->src == scanoutpix && dirty->slave_dst == - drmmode_crtc->scanout[scanout_id ^ drmmode_crtc->tear_free].pixmap) { + if (dirty->src == drmmode_crtc->prime_scanout_pixmap) { RegionPtr region; if (master_has_sync_shared_pixmap(scrn, dirty)) -- cgit v1.2.3 From 3a9f7e87c30b9f6334d38dfdd1cb15b28fe37fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 11 May 2017 18:57:25 +0900 Subject: Remove unused struct members from drmmode_display.h (Ported from amdgpu commit 462ac3341e5bfbded9086d3d9043821d19352b3e) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 1 - src/drmmode_display.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index e2899cf5..d0ecfa85 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2540,7 +2540,6 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); drmmode->scrn = pScrn; - drmmode->cpp = cpp; mode_res = drmModeGetResources(drmmode->fd); if (!mode_res) return FALSE; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index df2c4b7b..db68054a 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -41,8 +41,6 @@ typedef struct { int fd; - drmModeFBPtr mode_fb; - int cpp; struct radeon_bo_manager *bufmgr; ScrnInfoPtr scrn; #ifdef HAVE_LIBUDEV -- cgit v1.2.3 From 2b7d77b90108911777a11ecaa63435552000c958 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 16 May 2017 11:04:29 -0700 Subject: Use plain glamor_egl_create_textured_screen(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since 5064ffab631 (2014), glamor's implementation of _ext just drops the back_pixmap arg, which we were passing NULL (the default) to anyway. Signed-off-by: Eric Anholt Reviewed-by: Michel Dänzer --- src/radeon_glamor.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index 590c9f0c..e5e35553 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -61,11 +61,10 @@ radeon_glamor_create_screen_resources(ScreenPtr screen) return FALSE; #endif - if (!glamor_egl_create_textured_screen_ext(screen, - info->front_bo->handle, - scrn->displayWidth * - info->pixel_bytes, - NULL)) + if (!glamor_egl_create_textured_screen(screen, + info->front_bo->handle, + scrn->displayWidth * + info->pixel_bytes)) return FALSE; return TRUE; -- cgit v1.2.3 From d80d01a73c2eaba2e3649b7bc0a3541b3ff782f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 18 May 2017 11:12:34 +0900 Subject: Update URLs * Point to the amd-gfx mailing list * Specify the component in all bugzilla URLs * Use https:// for all HTML URLs Reviewed-by: Alex Deucher --- README | 16 ++++++++-------- configure.ac | 2 +- man/radeon.man | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README b/README index 4b92a185..bf7c6407 100644 --- a/README +++ b/README @@ -1,25 +1,25 @@ -xf86-video-ati - ATI Radeon video driver for the Xorg X server +xf86-video-ati - ATI/AMD Radeon video driver for the Xorg X server -All questions regarding this software should be directed at the -Xorg mailing list: +Patches and questions regarding this software should be directed at the +amd-gfx mailing list: - http://lists.freedesktop.org/mailman/listinfo/xorg + https://lists.freedesktop.org/mailman/listinfo/amd-gfx Please submit bug reports to the Xorg bugzilla: - https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon The master development code repository can be found at: git://anongit.freedesktop.org/git/xorg/driver/xf86-video-ati - http://cgit.freedesktop.org/xorg/driver/xf86-video-ati + https://cgit.freedesktop.org/xorg/driver/xf86-video-ati For patch submission instructions, see: - http://www.x.org/wiki/Development/Documentation/SubmittingPatches + https://www.x.org/wiki/Development/Documentation/SubmittingPatches For more information on the git code manager, see: - http://wiki.x.org/wiki/GitPage + https://wiki.x.org/wiki/GitPage diff --git a/configure.ac b/configure.ac index c9ccfb3d..700e01a5 100644 --- a/configure.ac +++ b/configure.ac @@ -24,7 +24,7 @@ AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], [7.9.99], - [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], + [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon], [xf86-video-ati]) AC_CONFIG_SRCDIR([Makefile.am]) diff --git a/man/radeon.man b/man/radeon.man index 9334d9e8..3e1723f2 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -392,17 +392,17 @@ __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(_ .IP " 1." 4 Wiki page: .RS 4 -http://www.x.org/wiki/radeon +https://www.x.org/wiki/radeon .RE .IP " 2." 4 Overview about radeon development code: .RS 4 -http://cgit.freedesktop.org/xorg/driver/xf86-video-ati/ +https://cgit.freedesktop.org/xorg/driver/xf86-video-ati/ .RE .IP " 3." 4 Mailing list: .RS 4 -http://lists.x.org/mailman/listinfo/xorg-driver-ati +https://lists.freedesktop.org/mailman/listinfo/amd-gfx .RE .IP " 4." 4 IRC channel: -- cgit v1.2.3 From ef95e3a3cc9189c8906fe5b4d70bfa9f1055d7ce Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 13 Jun 2017 09:32:44 -0400 Subject: modesetting: Validate the atom for enum properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The client could have said anything here, and if what they said doesn't actually name an atom NameForAtom() will return NULL, and strcmp() will be unhappy about that. [copied from xserver d4995a3936ae283b9080fdaa0905daa669ebacfc] Signed-off-by: Adam Jackson Reviewed-and-Tested-by: Michel Dänzer --- src/drmmode_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index d0ecfa85..9deaa575 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1685,7 +1685,8 @@ drmmode_output_set_property(xf86OutputPtr output, Atom property, if (value->type != XA_ATOM || value->format != 32 || value->size != 1) return FALSE; memcpy(&atom, value->data, 4); - name = NameForAtom(atom); + if (!(name = NameForAtom(atom))) + return FALSE; /* search for matching name string, then set its value down */ for (j = 0; j < p->mode_prop->count_enums; j++) { -- cgit v1.2.3 From 78fad9ca1635cca04b89807e3db029477cf46681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 26 Jun 2017 18:58:30 +0900 Subject: Include xf86Pci.h for DRICreatePCIBusID with xserver Git master The declaration has been moved there from dri.h. Reviewed-by: Alex Deucher --- src/radeon_probe.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/radeon_probe.c b/src/radeon_probe.c index aaace2b5..19295f00 100644 --- a/src/radeon_probe.c +++ b/src/radeon_probe.c @@ -48,7 +48,12 @@ #include "xf86.h" #include "xf86drmMode.h" + +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,19,99,1,0) +#include +#else #include "dri.h" +#endif #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #include -- cgit v1.2.3 From c9dd28cb0c9c3de676eadac61e727732510f6b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 22 Jun 2017 12:38:55 +0900 Subject: Only call drmmode_scanout_free for non-GPU screens in LeaveVT Destroying the scanout buffers of GPU screens resulted in a crash when switching back to the Xorg VT. Fixes: 4cfa4615f79f ("Use drmmode_crtc_scanout_* helpers for RandR 1.4 scanout pixmaps") Reviewed-by: Alex Deucher --- src/radeon_kms.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index c4bdfcfa..5637e7f8 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2478,7 +2478,8 @@ void RADEONLeaveVT_KMS(VT_FUNC_ARGS_DECL) radeon_drop_drm_master(pScrn); xf86RotateFreeShadow(pScrn); - drmmode_scanout_free(pScrn); + if (!pScrn->is_gpu) + drmmode_scanout_free(pScrn); xf86_hide_cursors (pScrn); info->accel_state->XInited3D = FALSE; -- cgit v1.2.3 From bc46ffdf71ab3dfa0f95572529e818f2b619d380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 27 Jun 2017 18:19:31 +0900 Subject: Increase reference count of FB assigned to drmmode_crtc->flip_pending Otherwise, it could happen that we destroy the FB before the flip completes, resulting in use-after-free and most likely a crash. (Ported from amdgpu commit af7221e1c4d2dbdfd488eb0976a835584ea8441c) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 8 ++++++-- src/radeon_kms.c | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 9deaa575..dd394ec1 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2369,8 +2369,11 @@ void drmmode_clear_pending_flip(xf86CrtcPtr crtc) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + ScrnInfoPtr scrn = crtc->scrn; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - drmmode_crtc->flip_pending = NULL; + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, + NULL); if (!crtc->enabled || (drmmode_crtc->pending_dpms_mode != DPMSModeOn && @@ -3030,7 +3033,8 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, goto flip_error; } - drmmode_crtc->flip_pending = fb; + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, + fb); drm_queue_seq = 0; } diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 5637e7f8..691fcdf5 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -815,8 +815,8 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) return; } - drmmode_crtc->flip_pending = - radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, + radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap)); if (!drmmode_crtc->flip_pending) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Failed to get FB for PRIME flip.\n"); @@ -1110,8 +1110,8 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, return; } - drmmode_crtc->flip_pending = - radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, + radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap)); if (!drmmode_crtc->flip_pending) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Failed to get FB for scanout flip.\n"); -- cgit v1.2.3 From 19626bce4e5e31c863eedb503ea3884ac3f60bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 27 Jun 2017 18:32:28 +0900 Subject: Improve drmmode_fb_reference debugging code If a reference count is <= 0, call FatalError with the call location (in case it doesn't get resolved in the backtrace printed by FatalError). (Ported from amdgpu commit 1b6ff5fd9933c00ec1ec90dfc62e0b531927749b) Reviewed-by: Alex Deucher --- src/drmmode_display.h | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/drmmode_display.h b/src/drmmode_display.h index db68054a..dde27a00 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -141,29 +141,36 @@ enum drmmode_flip_sync { static inline void -drmmode_fb_reference(int drm_fd, struct drmmode_fb **old, struct drmmode_fb *new) +drmmode_fb_reference_loc(int drm_fd, struct drmmode_fb **old, struct drmmode_fb *new, + const char *caller, unsigned line) { if (new) { - if (new->refcnt <= 0) - ErrorF("New FB's refcnt was %d in %s\n", new->refcnt, __func__); - else - new->refcnt++; + if (new->refcnt <= 0) { + FatalError("New FB's refcnt was %d at %s:%u", + new->refcnt, caller, line); + } + + new->refcnt++; } if (*old) { if ((*old)->refcnt <= 0) { - ErrorF("Old FB's refcnt was %d in %s\n", (*old)->refcnt, __func__); - } else { - if (--(*old)->refcnt == 0) { - drmModeRmFB(drm_fd, (*old)->handle); - free(*old); - } + FatalError("Old FB's refcnt was %d at %s:%u", + (*old)->refcnt, caller, line); + } + + if (--(*old)->refcnt == 0) { + drmModeRmFB(drm_fd, (*old)->handle); + free(*old); } } *old = new; } +#define drmmode_fb_reference(fd, old, new) \ + drmmode_fb_reference_loc(fd, old, new, __func__, __LINE__) + extern int drmmode_page_flip_target_absolute(RADEONEntPtr pRADEONEnt, drmmode_crtc_private_ptr drmmode_crtc, -- cgit v1.2.3 From df88d51c5005476e6fbfca3f31b54be079ec5aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 27 Jun 2017 19:15:18 +0900 Subject: Use pRADEONEnt->fd exclusively for the DRM file descriptor This brings us closer to amdgpu. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 151 +++++++++++++++++++++++++------------------------ src/drmmode_display.h | 1 - src/radeon.h | 14 +++-- src/radeon_accel.c | 4 +- src/radeon_bo_helper.c | 8 ++- src/radeon_dri2.c | 54 ++++++++++-------- src/radeon_dri2.h | 1 - src/radeon_dri3.c | 3 +- src/radeon_exa.c | 4 +- src/radeon_glamor.c | 3 +- src/radeon_kms.c | 70 ++++++++++++----------- src/radeon_present.c | 13 +++-- 12 files changed, 172 insertions(+), 154 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index dd394ec1..4b964b7b 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -272,7 +272,7 @@ int drmmode_get_current_ust(int drm_fd, CARD64 *ust) int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc) { ScrnInfoPtr scrn = crtc->scrn; - RADEONInfoPtr info = RADEONPTR(scrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); drmVBlank vbl; int ret; @@ -280,7 +280,7 @@ int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc) vbl.request.type |= radeon_populate_vbl_request_type(crtc); vbl.request.sequence = 0; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); + ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "get vblank counter failed: %s\n", strerror(errno)); @@ -298,7 +298,7 @@ drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; ScrnInfoPtr scrn = crtc->scrn; - RADEONInfoPtr info = RADEONPTR(scrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); CARD64 ust; int ret; @@ -318,7 +318,7 @@ drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode) vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.type |= radeon_populate_vbl_request_type(crtc); vbl.request.sequence = 0; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); + ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); if (ret) xf86DrvMsg(scrn->scrnIndex, X_ERROR, "%s cannot get last vblank counter\n", @@ -345,7 +345,7 @@ drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode) * Off->On transition: calculate and accumulate the * number of interpolated vblanks while we were in Off state */ - ret = drmmode_get_current_ust(info->dri2.drm_fd, &ust); + ret = drmmode_get_current_ust(pRADEONEnt->fd, &ust); if (ret) xf86DrvMsg(scrn->scrnIndex, X_ERROR, "%s cannot get current time\n", __func__); @@ -365,7 +365,7 @@ static void drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); /* Disable unused CRTCs */ if (!crtc->enabled || mode != DPMSModeOn) { @@ -373,9 +373,9 @@ drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) if (drmmode_crtc->flip_pending) return; - drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + drmModeSetCrtc(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 0, 0, NULL, 0, NULL); - drmmode_fb_reference(drmmode->fd, &drmmode_crtc->fb, NULL); + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL); } else if (drmmode_crtc->dpms_mode != DPMSModeOn) crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); @@ -385,6 +385,7 @@ static PixmapPtr create_pixmap_for_fbcon(drmmode_ptr drmmode, ScrnInfoPtr pScrn, int fbcon_id) { + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); PixmapPtr pixmap = info->fbcon_pixmap; struct radeon_bo *bo; @@ -394,7 +395,7 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, if (pixmap) return pixmap; - fbcon = drmModeGetFB(drmmode->fd, fbcon_id); + fbcon = drmModeGetFB(pRADEONEnt->fd, fbcon_id); if (fbcon == NULL) return NULL; @@ -404,7 +405,7 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, goto out_free_fb; flink.handle = fbcon->handle; - if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { + if (ioctl(pRADEONEnt->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't flink fbcon handle\n"); goto out_free_fb; @@ -812,8 +813,9 @@ drmmode_crtc_gamma_do_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, uint16_t *blue, int size) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); - drmModeCrtcSetGamma(drmmode_crtc->drmmode->fd, + drmModeCrtcSetGamma(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, size, red, green, blue); } @@ -825,6 +827,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, ScrnInfoPtr pScrn = crtc->scrn; ScreenPtr pScreen = pScrn->pScreen; RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; unsigned scanout_id = 0; @@ -907,13 +910,13 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, if (!fb) fb = radeon_pixmap_get_fb(pScreen->GetWindowPixmap(pScreen->root)); if (!fb) { - fb = radeon_fb_create(drmmode->fd, pScrn->virtualX, + fb = radeon_fb_create(pRADEONEnt->fd, pScrn->virtualX, pScrn->virtualY, pScrn->depth, pScrn->bitsPerPixel, pScrn->displayWidth * info->pixel_bytes, info->front_bo->handle); /* Prevent refcnt of ad-hoc FBs from reaching 2 */ - drmmode_fb_reference(drmmode->fd, &drmmode_crtc->fb, NULL); + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL); drmmode_crtc->fb = fb; } if (!fb) { @@ -923,10 +926,10 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, /* Wait for any pending flip to finish */ do {} while (drmmode_crtc->flip_pending && - drmHandleEvent(drmmode->fd, + drmHandleEvent(pRADEONEnt->fd, &drmmode->event_context) > 0); - if (drmModeSetCrtc(drmmode->fd, + if (drmModeSetCrtc(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, fb->handle, x, y, output_ids, output_count, &kmode) != 0) { @@ -935,7 +938,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, goto done; } else { ret = TRUE; - drmmode_fb_reference(drmmode->fd, &drmmode_crtc->fb, fb); + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, fb); } if (pScreen) @@ -1006,7 +1009,7 @@ static void drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); #if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7 if (crtc->driverIsPerformingTransform) { @@ -1016,7 +1019,7 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) } #endif - drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); + drmModeMoveCursor(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); } #if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7 @@ -1138,9 +1141,9 @@ drmmode_hide_cursor (xf86CrtcPtr crtc) ScrnInfoPtr pScrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, + drmModeSetCursor(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, 0, info->cursor_w, info->cursor_h); } @@ -1151,7 +1154,7 @@ drmmode_show_cursor (xf86CrtcPtr crtc) ScrnInfoPtr pScrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); uint32_t handle = drmmode_crtc->cursor_bo->handle; static Bool use_set_cursor2 = TRUE; @@ -1191,7 +1194,7 @@ drmmode_show_cursor (xf86CrtcPtr crtc) } ret = - drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + drmModeSetCursor2(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, handle, info->cursor_w, info->cursor_h, xhot, yhot); if (ret == -EINVAL) @@ -1200,7 +1203,7 @@ drmmode_show_cursor (xf86CrtcPtr crtc) return; } - drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, + drmModeSetCursor(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, handle, info->cursor_w, info->cursor_h); } @@ -1347,8 +1350,7 @@ int drmmode_get_crtc_id(xf86CrtcPtr crtc) void drmmode_crtc_hw_id(xf86CrtcPtr crtc) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - ScrnInfoPtr pScrn = crtc->scrn; - RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); struct drm_radeon_info ginfo; int r; uint32_t tmp; @@ -1357,7 +1359,7 @@ void drmmode_crtc_hw_id(xf86CrtcPtr crtc) ginfo.request = 0x4; tmp = drmmode_crtc->mode_crtc->crtc_id; ginfo.value = (uintptr_t)&tmp; - r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); + r = drmCommandWriteRead(pRADEONEnt->fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); if (r) { drmmode_crtc->hw_id = -1; return; @@ -1377,7 +1379,7 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res return 0; drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); - drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]); + drmmode_crtc->mode_crtc = drmModeGetCrtc(pRADEONEnt->fd, mode_res->crtcs[num]); drmmode_crtc->drmmode = drmmode; drmmode_crtc->dpms_mode = DPMSModeOff; drmmode_crtc->pending_dpms_mode = DPMSModeOff; @@ -1397,11 +1399,11 @@ drmmode_output_detect(xf86OutputPtr output) { /* go to the hw and retrieve a new output struct */ drmmode_output_private_ptr drmmode_output = output->driver_private; - drmmode_ptr drmmode = drmmode_output->drmmode; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(output->scrn); xf86OutputStatus status; drmModeFreeConnector(drmmode_output->mode_output); - drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id); + drmmode_output->mode_output = drmModeGetConnector(pRADEONEnt->fd, drmmode_output->output_id); if (!drmmode_output->mode_output) return XF86OutputStatusDisconnected; @@ -1431,7 +1433,7 @@ drmmode_output_get_modes(xf86OutputPtr output) { drmmode_output_private_ptr drmmode_output = output->driver_private; drmModeConnectorPtr koutput = drmmode_output->mode_output; - drmmode_ptr drmmode = drmmode_output->drmmode; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(output->scrn); int i; DisplayModePtr Modes = NULL, Mode; drmModePropertyPtr props; @@ -1442,12 +1444,12 @@ drmmode_output_get_modes(xf86OutputPtr output) /* look for an EDID property */ for (i = 0; i < koutput->count_props; i++) { - props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + props = drmModeGetProperty(pRADEONEnt->fd, koutput->props[i]); if (props && (props->flags & DRM_MODE_PROP_BLOB)) { if (!strcmp(props->name, "EDID")) { if (drmmode_output->edid_blob) drmModeFreePropertyBlob(drmmode_output->edid_blob); - drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); + drmmode_output->edid_blob = drmModeGetPropertyBlob(pRADEONEnt->fd, koutput->prop_values[i]); } } if (props) @@ -1501,7 +1503,7 @@ drmmode_output_dpms(xf86OutputPtr output, int mode) drmmode_output_private_ptr drmmode_output = output->driver_private; xf86CrtcPtr crtc = output->crtc; drmModeConnectorPtr koutput = drmmode_output->mode_output; - drmmode_ptr drmmode = drmmode_output->drmmode; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(output->scrn); if (!koutput) return; @@ -1516,7 +1518,7 @@ drmmode_output_dpms(xf86OutputPtr output, int mode) return; } - drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id, + drmModeConnectorSetProperty(pRADEONEnt->fd, koutput->connector_id, drmmode_output->dpms_enum_id, mode); if (mode == DPMSModeOn && crtc) { @@ -1553,7 +1555,7 @@ drmmode_output_create_resources(xf86OutputPtr output) RADEONInfoPtr info = RADEONPTR(output->scrn); drmmode_output_private_ptr drmmode_output = output->driver_private; drmModeConnectorPtr mode_output = drmmode_output->mode_output; - drmmode_ptr drmmode = drmmode_output->drmmode; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(output->scrn); drmModePropertyPtr drmmode_prop, tearfree_prop; int i, j, err; @@ -1563,7 +1565,7 @@ drmmode_output_create_resources(xf86OutputPtr output) drmmode_output->num_props = 0; for (i = 0, j = 0; i < mode_output->count_props; i++) { - drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]); + drmmode_prop = drmModeGetProperty(pRADEONEnt->fd, mode_output->props[i]); if (drmmode_property_ignore(drmmode_prop)) { drmModeFreeProperty(drmmode_prop); continue; @@ -1657,7 +1659,7 @@ drmmode_output_set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) { drmmode_output_private_ptr drmmode_output = output->driver_private; - drmmode_ptr drmmode = drmmode_output->drmmode; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(output->scrn); int i; for (i = 0; i < drmmode_output->num_props; i++) { @@ -1674,7 +1676,7 @@ drmmode_output_set_property(xf86OutputPtr output, Atom property, return FALSE; val = *(uint32_t *)value->data; - drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, + drmModeConnectorSetProperty(pRADEONEnt->fd, drmmode_output->output_id, p->mode_prop->prop_id, (uint64_t)val); return TRUE; } else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) { @@ -1703,7 +1705,7 @@ drmmode_output_set_property(xf86OutputPtr output, Atom property, } } } else { - drmModeConnectorSetProperty(drmmode->fd, + drmModeConnectorSetProperty(pRADEONEnt->fd, drmmode_output->output_id, p->mode_prop->prop_id, p->mode_prop->enums[j].value); @@ -1876,6 +1878,7 @@ static unsigned int drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, int *num_dvi, int *num_hdmi, int dynamic) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); xf86OutputPtr output; drmModeConnectorPtr koutput; @@ -1887,15 +1890,15 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r int i; const char *s; - koutput = drmModeGetConnector(drmmode->fd, mode_res->connectors[num]); + koutput = drmModeGetConnector(pRADEONEnt->fd, mode_res->connectors[num]); if (!koutput) return 0; for (i = 0; i < koutput->count_props; i++) { - props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + props = drmModeGetProperty(pRADEONEnt->fd, koutput->props[i]); if (props && (props->flags & DRM_MODE_PROP_BLOB)) { if (!strcmp(props->name, "PATH")) { - path_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); + path_blob = drmModeGetPropertyBlob(pRADEONEnt->fd, koutput->prop_values[i]); drmModeFreeProperty(props); break; } @@ -1909,7 +1912,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r } for (i = 0; i < koutput->count_encoders; i++) { - kencoders[i] = drmModeGetEncoder(drmmode->fd, koutput->encoders[i]); + kencoders[i] = drmModeGetEncoder(pRADEONEnt->fd, koutput->encoders[i]); if (!kencoders[i]) { goto out_free_encoders; } @@ -1982,7 +1985,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r output->possible_clones = 0; for (i = 0; i < koutput->count_props; i++) { - props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + props = drmModeGetProperty(pRADEONEnt->fd, koutput->props[i]); if (props && (props->flags & DRM_MODE_PROP_ENUM)) { if (!strcmp(props->name, "DPMS")) { drmmode_output->dpms_enum_id = koutput->props[i]; @@ -2418,6 +2421,7 @@ static void drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); drmmode_flipdata_ptr flipdata = event_data; /* Is this the event whose info shall be delivered to higher level? */ @@ -2440,7 +2444,7 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even free(flipdata); } - drmmode_fb_reference(drmmode_crtc->drmmode->fd, &drmmode_crtc->fb, + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, drmmode_crtc->flip_pending); drmmode_clear_pending_flip(crtc); } @@ -2454,23 +2458,26 @@ static void drm_wakeup_handler(pointer data, int err, pointer p) #endif { - drmmode_ptr drmmode = data; + ScrnInfoPtr scrn = data; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + RADEONInfoPtr info = RADEONPTR(scrn); + #if !HAVE_NOTIFY_FD fd_set *read_mask = p; - if (err >= 0 && FD_ISSET(drmmode->fd, read_mask)) + if (err >= 0 && FD_ISSET(pRADEONEnt->fd, read_mask)) #endif { - drmHandleEvent(drmmode->fd, &drmmode->event_context); + drmHandleEvent(pRADEONEnt->fd, &info->drmmode.event_context); } } -static Bool drmmode_probe_page_flip_target(drmmode_ptr drmmode) +static Bool drmmode_probe_page_flip_target(RADEONEntPtr pRADEONEnt) { #ifdef DRM_CAP_PAGE_FLIP_TARGET uint64_t cap_value; - return drmGetCap(drmmode->fd, DRM_CAP_PAGE_FLIP_TARGET, + return drmGetCap(pRADEONEnt->fd, DRM_CAP_PAGE_FLIP_TARGET, &cap_value) == 0 && cap_value != 0; #else return FALSE; @@ -2478,13 +2485,12 @@ static Bool drmmode_probe_page_flip_target(drmmode_ptr drmmode) } static int -drmmode_page_flip(drmmode_crtc_private_ptr drmmode_crtc, int fb_id, +drmmode_page_flip(RADEONEntPtr pRADEONEnt, + drmmode_crtc_private_ptr drmmode_crtc, int fb_id, uint32_t flags, uintptr_t drm_queue_seq) { - drmmode_ptr drmmode = drmmode_crtc->drmmode; - flags |= DRM_MODE_PAGE_FLIP_EVENT; - return drmModePageFlip(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + return drmModePageFlip(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, fb_id, flags, (void*)drm_queue_seq); } @@ -2496,17 +2502,16 @@ drmmode_page_flip_target_absolute(RADEONEntPtr pRADEONEnt, { #ifdef DRM_MODE_PAGE_FLIP_TARGET if (pRADEONEnt->has_page_flip_target) { - drmmode_ptr drmmode = drmmode_crtc->drmmode; - flags |= DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE; - return drmModePageFlipTarget(drmmode->fd, + return drmModePageFlipTarget(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, fb_id, flags, (void*)drm_queue_seq, target_msc); } #endif - return drmmode_page_flip(drmmode_crtc, fb_id, flags, drm_queue_seq); + return drmmode_page_flip(pRADEONEnt, drmmode_crtc, fb_id, flags, + drm_queue_seq); } int @@ -2517,17 +2522,16 @@ drmmode_page_flip_target_relative(RADEONEntPtr pRADEONEnt, { #ifdef DRM_MODE_PAGE_FLIP_TARGET if (pRADEONEnt->has_page_flip_target) { - drmmode_ptr drmmode = drmmode_crtc->drmmode; - flags |= DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_PAGE_FLIP_TARGET_RELATIVE; - return drmModePageFlipTarget(drmmode->fd, + return drmModePageFlipTarget(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, fb_id, flags, (void*)drm_queue_seq, target_msc); } #endif - return drmmode_page_flip(drmmode_crtc, fb_id, flags, drm_queue_seq); + return drmmode_page_flip(pRADEONEnt, drmmode_crtc, fb_id, flags, + drm_queue_seq); } Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) @@ -2544,7 +2548,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); drmmode->scrn = pScrn; - mode_res = drmModeGetResources(drmmode->fd); + mode_res = drmModeGetResources(pRADEONEnt->fd); if (!mode_res) return FALSE; @@ -2594,7 +2598,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) drmmode->event_context.vblank_handler = radeon_drm_queue_handler; drmmode->event_context.page_flip_handler = radeon_drm_queue_handler; - pRADEONEnt->has_page_flip_target = drmmode_probe_page_flip_target(drmmode); + pRADEONEnt->has_page_flip_target = drmmode_probe_page_flip_target(pRADEONEnt); drmModeFreeResources(mode_res); return TRUE; @@ -2611,11 +2615,11 @@ void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode) info->drmmode_inited = TRUE; if (pRADEONEnt->fd_wakeup_registered != serverGeneration) { #if HAVE_NOTIFY_FD - SetNotifyFd(drmmode->fd, drm_notify_fd, X_NOTIFY_READ, drmmode); + SetNotifyFd(pRADEONEnt->fd, drm_notify_fd, X_NOTIFY_READ, pScrn); #else - AddGeneralSocket(drmmode->fd); + AddGeneralSocket(pRADEONEnt->fd); RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, - drm_wakeup_handler, drmmode); + drm_wakeup_handler, pScrn); #endif pRADEONEnt->fd_wakeup_registered = serverGeneration; pRADEONEnt->fd_wakeup_ref = 1; @@ -2636,11 +2640,11 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode) if (pRADEONEnt->fd_wakeup_registered == serverGeneration && !--pRADEONEnt->fd_wakeup_ref) { #if HAVE_NOTIFY_FD - RemoveNotifyFd(drmmode->fd); + RemoveNotifyFd(pRADEONEnt->fd); #else - RemoveGeneralSocket(drmmode->fd); + RemoveGeneralSocket(pRADEONEnt->fd); RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, - drm_wakeup_handler, drmmode); + drm_wakeup_handler, pScrn); #endif } @@ -2682,6 +2686,7 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); int c; for (c = 0; c < config->num_crtc; c++) { @@ -2694,10 +2699,10 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, if (!crtc->enabled) { if (set_hw) { drmmode_do_crtc_dpms(crtc, DPMSModeOff); - drmModeSetCrtc(drmmode->fd, + drmModeSetCrtc(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 0, 0, NULL, 0, NULL); - drmmode_fb_reference(drmmode->fd, + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL); } continue; @@ -2812,7 +2817,7 @@ radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode) Bool changed = FALSE; int num_dvi = 0, num_hdmi = 0; - mode_res = drmModeGetResources(drmmode->fd); + mode_res = drmModeGetResources(pRADEONEnt->fd); if (!mode_res) goto out; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index dde27a00..ba1a7bc8 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -40,7 +40,6 @@ #endif typedef struct { - int fd; struct radeon_bo_manager *bufmgr; ScrnInfoPtr scrn; #ifdef HAVE_LIBUDEV diff --git a/src/radeon.h b/src/radeon.h index febe580b..ca509561 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -694,7 +694,9 @@ uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix); static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) { #ifdef USE_GLAMOR - RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen)); + ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + RADEONInfoPtr info = RADEONPTR(scrn); if (info->use_glamor) { struct radeon_pixmap *priv; @@ -711,7 +713,7 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) radeon_bo_unref(priv->bo); } - drmmode_fb_reference(info->drmmode.fd, &priv->fb, NULL); + drmmode_fb_reference(pRADEONEnt->fd, &priv->fb, NULL); if (!bo) { free(priv); @@ -831,7 +833,9 @@ radeon_pixmap_create_fb(int drm_fd, PixmapPtr pix) static inline struct drmmode_fb* radeon_pixmap_get_fb(PixmapPtr pix) { - RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pix->drawable.pScreen)); + ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + RADEONInfoPtr info = RADEONPTR(scrn); #ifdef USE_GLAMOR if (info->use_glamor) { @@ -841,7 +845,7 @@ radeon_pixmap_get_fb(PixmapPtr pix) return NULL; if (!priv->fb) - priv->fb = radeon_pixmap_create_fb(info->drmmode.fd, pix); + priv->fb = radeon_pixmap_create_fb(pRADEONEnt->fd, pix); return priv->fb; } else @@ -855,7 +859,7 @@ radeon_pixmap_get_fb(PixmapPtr pix) return NULL; if (!driver_priv->fb) - driver_priv->fb = radeon_pixmap_create_fb(info->drmmode.fd, pix); + driver_priv->fb = radeon_pixmap_create_fb(pRADEONEnt->fd, pix); return driver_priv->fb; } diff --git a/src/radeon_accel.c b/src/radeon_accel.c index 1def2a3f..fc80ed74 100644 --- a/src/radeon_accel.c +++ b/src/radeon_accel.c @@ -94,11 +94,11 @@ static int RADEONDRMGetNumPipes(ScrnInfoPtr pScrn, int *num_pipes) { - RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); struct drm_radeon_info np2; np2.value = (unsigned long)num_pipes; np2.request = RADEON_INFO_NUM_GB_PIPES; - return drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &np2, sizeof(np2)); + return drmCommandWriteRead(pRADEONEnt->fd, DRM_RADEON_INFO, &np2, sizeof(np2)); } /* Initialize the acceleration hardware */ diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c index 933dc7b3..a8ba7618 100644 --- a/src/radeon_bo_helper.c +++ b/src/radeon_bo_helper.c @@ -201,7 +201,9 @@ Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle) struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap); #ifdef USE_GLAMOR ScreenPtr screen = pixmap->drawable.pScreen; - RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen)); + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + RADEONInfoPtr info = RADEONPTR(scrn); #endif if (bo) { @@ -230,7 +232,7 @@ Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle) if (fd < 0) return FALSE; - r = drmPrimeFDToHandle(info->dri2.drm_fd, fd, &priv->handle); + r = drmPrimeFDToHandle(pRADEONEnt->fd, fd, &priv->handle); close(fd); if (r == 0) { struct drm_radeon_gem_set_tiling args = { .handle = priv->handle }; @@ -238,7 +240,7 @@ Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle) priv->handle_valid = TRUE; *handle = priv->handle; - if (drmCommandWriteRead(info->dri2.drm_fd, + if (drmCommandWriteRead(pRADEONEnt->fd, DRM_RADEON_GEM_GET_TILING, &args, sizeof(args)) == 0) priv->tiling_flags = args.tiling_flags; diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index cc72bd52..435bf539 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -81,7 +81,7 @@ static DevPrivateKeyRec dri2_window_private_key_rec; /* Get GEM flink name for a pixmap */ static Bool -radeon_get_flink_name(RADEONInfoPtr info, PixmapPtr pixmap, uint32_t *name) +radeon_get_flink_name(RADEONEntPtr pRADEONEnt, PixmapPtr pixmap, uint32_t *name) { struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap); struct drm_gem_flink flink; @@ -90,7 +90,7 @@ radeon_get_flink_name(RADEONInfoPtr info, PixmapPtr pixmap, uint32_t *name) return radeon_gem_get_kernel_name(bo, name) == 0; if (radeon_get_pixmap_handle(pixmap, &flink.handle)) { - if (drmIoctl(info->dri2.drm_fd, DRM_IOCTL_GEM_FLINK, &flink) != 0) + if (drmIoctl(pRADEONEnt->fd, DRM_IOCTL_GEM_FLINK, &flink) != 0) return FALSE; *name = flink.name; @@ -107,6 +107,7 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen, unsigned int format) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); BufferPtr buffers; struct dri2_buffer_priv *privates; @@ -253,7 +254,7 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen, pixmap->refcnt++; } - if (!radeon_get_flink_name(info, pixmap, &buffers->name)) + if (!radeon_get_flink_name(pRADEONEnt, pixmap, &buffers->name)) goto error; } @@ -523,13 +524,13 @@ static Bool radeon_dri2_get_crtc_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc) drmmode_crtc_get_ust_msc(crtc, ust, msc) != Success) { /* CRTC is not running, extrapolate MSC and timestamp */ ScrnInfoPtr scrn = crtc->scrn; - RADEONInfoPtr info = RADEONPTR(scrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); CARD64 now, delta_t, delta_seq; if (!drmmode_crtc->dpms_last_ust) return FALSE; - if (drmmode_get_current_ust(info->dri2.drm_fd, &now) != 0) { + if (drmmode_get_current_ust(pRADEONEnt->fd, &now) != 0) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "%s cannot get current time\n", __func__); return FALSE; @@ -689,7 +690,9 @@ static Bool update_front(DrawablePtr draw, DRI2BufferPtr front) { PixmapPtr pixmap; - RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(draw->pScreen)); + ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + RADEONInfoPtr info = RADEONPTR(scrn); struct dri2_buffer_priv *priv = front->driverPrivate; pixmap = get_drawable_pixmap(draw); @@ -697,7 +700,7 @@ update_front(DrawablePtr draw, DRI2BufferPtr front) if (!info->use_glamor) exaMoveInPixmap(pixmap); - if (!radeon_get_flink_name(info, pixmap, &front->name)) { + if (!radeon_get_flink_name(pRADEONEnt, pixmap, &front->name)) { (*draw->pScreen->DestroyPixmap)(pixmap); return FALSE; } @@ -937,7 +940,7 @@ CARD32 radeon_dri2_extrapolate_msc_delay(xf86CrtcPtr crtc, CARD64 *target_msc, { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; ScrnInfoPtr pScrn = crtc->scrn; - RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); int nominal_frame_rate = drmmode_crtc->dpms_last_fps; CARD64 last_vblank_ust = drmmode_crtc->dpms_last_ust; uint32_t last_vblank_seq = drmmode_crtc->dpms_last_seq; @@ -950,7 +953,7 @@ CARD32 radeon_dri2_extrapolate_msc_delay(xf86CrtcPtr crtc, CARD64 *target_msc, *target_msc = 0; return FALLBACK_SWAP_DELAY; } - ret = drmmode_get_current_ust(info->dri2.drm_fd, &now); + ret = drmmode_get_current_ust(pRADEONEnt->fd, &now); if (ret) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s cannot get current time\n", __func__); @@ -1028,7 +1031,7 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) DRI2FrameEventPtr event_info = (DRI2FrameEventPtr)data; xf86CrtcPtr crtc = event_info->crtc; ScrnInfoPtr scrn; - RADEONInfoPtr info; + RADEONEntPtr pRADEONEnt; CARD64 drm_now; int ret; CARD64 delta_t, delta_seq, frame; @@ -1051,13 +1054,13 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) } scrn = crtc->scrn; - info = RADEONPTR(scrn); - ret = drmmode_get_current_ust(info->dri2.drm_fd, &drm_now); + pRADEONEnt = RADEONEntPriv(scrn); + ret = drmmode_get_current_ust(pRADEONEnt->fd, &drm_now); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "%s cannot get current time\n", __func__); if (event_info->drm_queue_seq) - radeon_drm_queue_handler(info->dri2.drm_fd, 0, 0, 0, + radeon_drm_queue_handler(pRADEONEnt->fd, 0, 0, 0, (void*)event_info->drm_queue_seq); else radeon_dri2_frame_event_handler(crtc, 0, 0, data); @@ -1073,7 +1076,7 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) delta_seq /= 1000000; frame = (CARD64)drmmode_crtc->dpms_last_seq + delta_seq; if (event_info->drm_queue_seq) - radeon_drm_queue_handler(info->dri2.drm_fd, frame, drm_now / 1000000, + radeon_drm_queue_handler(pRADEONEnt->fd, frame, drm_now / 1000000, drm_now % 1000000, (void*)event_info->drm_queue_seq); else @@ -1104,7 +1107,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, { ScreenPtr screen = draw->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - RADEONInfoPtr info = RADEONPTR(scrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); DRI2FrameEventPtr wait_info = NULL; uintptr_t drm_queue_seq = 0; xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE); @@ -1152,7 +1155,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.type |= radeon_populate_vbl_request_type(crtc); vbl.request.sequence = 0; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); + ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "get vblank counter failed: %s\n", strerror(errno)); @@ -1190,7 +1193,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, vbl.request.type |= radeon_populate_vbl_request_type(crtc); vbl.request.sequence = target_msc - msc_delta; vbl.request.signal = drm_queue_seq; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); + ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "get vblank counter failed: %s\n", strerror(errno)); @@ -1221,7 +1224,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, vbl.request.sequence += divisor; vbl.request.signal = drm_queue_seq; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); + ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "get vblank counter failed: %s\n", strerror(errno)); @@ -1266,7 +1269,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, { ScreenPtr screen = draw->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - RADEONInfoPtr info = RADEONPTR(scrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE); uint32_t msc_delta; drmVBlank vbl; @@ -1339,7 +1342,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.type |= radeon_populate_vbl_request_type(crtc); vbl.request.sequence = 0; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); + ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "first get vblank counter failed: %s\n", @@ -1387,7 +1390,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, vbl.request.sequence = *target_msc - msc_delta; vbl.request.signal = drm_queue_seq; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); + ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "divisor 0 get vblank counter failed: %s\n", @@ -1432,7 +1435,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, vbl.request.sequence -= flip; vbl.request.signal = drm_queue_seq; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); + ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "final get vblank counter failed: %s\n", @@ -1475,6 +1478,7 @@ Bool radeon_dri2_screen_init(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); DRI2InfoRec dri2_info = { 0 }; const char *driverNames[2]; @@ -1483,7 +1487,7 @@ radeon_dri2_screen_init(ScreenPtr pScreen) if (!info->dri2.available) return FALSE; - info->dri2.device_name = drmGetDeviceNameFromFd(info->dri2.drm_fd); + info->dri2.device_name = drmGetDeviceNameFromFd(pRADEONEnt->fd); if ( (info->ChipFamily >= CHIP_FAMILY_TAHITI) ) { dri2_info.driverName = SI_DRIVER_NAME; @@ -1496,7 +1500,7 @@ radeon_dri2_screen_init(ScreenPtr pScreen) } else { dri2_info.driverName = RADEON_DRIVER_NAME; } - dri2_info.fd = info->dri2.drm_fd; + dri2_info.fd = pRADEONEnt->fd; dri2_info.deviceName = info->dri2.device_name; dri2_info.version = DRI2INFOREC_VERSION; dri2_info.CreateBuffer = radeon_dri2_create_buffer; @@ -1513,7 +1517,7 @@ radeon_dri2_screen_init(ScreenPtr pScreen) #ifdef DRM_CAP_VBLANK_HIGH_CRTC uint64_t cap_value; - if (drmGetCap(info->dri2.drm_fd, DRM_CAP_VBLANK_HIGH_CRTC, &cap_value)) { + if (drmGetCap(pRADEONEnt->fd, DRM_CAP_VBLANK_HIGH_CRTC, &cap_value)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel " "for VBLANKs on CRTC > 1\n"); scheduling_works = FALSE; diff --git a/src/radeon_dri2.h b/src/radeon_dri2.h index 9ba47c78..4d3f377b 100644 --- a/src/radeon_dri2.h +++ b/src/radeon_dri2.h @@ -31,7 +31,6 @@ struct radeon_dri2 { drmVersionPtr pKernelDRMVersion; - int drm_fd; Bool available; Bool enabled; char *device_name; diff --git a/src/radeon_dri3.c b/src/radeon_dri3.c index fa24abae..3e689ffd 100644 --- a/src/radeon_dri3.c +++ b/src/radeon_dri3.c @@ -43,6 +43,7 @@ static int open_master_node(ScreenPtr screen, int *out) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); RADEONInfoPtr info = RADEONPTR(scrn); drm_magic_t magic; int fd; @@ -76,7 +77,7 @@ static int open_master_node(ScreenPtr screen, int *out) } } - if (drmAuthMagic(info->dri2.drm_fd, magic) < 0) { + if (drmAuthMagic(pRADEONEnt->fd, magic) < 0) { close(fd); return BadMatch; } diff --git a/src/radeon_exa.c b/src/radeon_exa.c index d8dd7fdc..d362e5d9 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -300,7 +300,7 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv) { - RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pScreen)); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(xf86ScreenToScrn(pScreen)); struct radeon_exa_pixmap_priv *driver_priv = driverPriv; if (!driverPriv) @@ -308,7 +308,7 @@ void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv) if (driver_priv->bo) radeon_bo_unref(driver_priv->bo); - drmmode_fb_reference(info->drmmode.fd, &driver_priv->fb, NULL); + drmmode_fb_reference(pRADEONEnt->fd, &driver_priv->fb, NULL); free(driverPriv); } diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index e5e35553..01ff5609 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -74,6 +74,7 @@ radeon_glamor_create_screen_resources(ScreenPtr screen) Bool radeon_glamor_pre_init(ScrnInfoPtr scrn) { + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); RADEONInfoPtr info = RADEONPTR(scrn); pointer glamor_module; CARD32 version; @@ -135,7 +136,7 @@ radeon_glamor_pre_init(ScrnInfoPtr scrn) "Incompatible glamor version, required >= 0.3.0.\n"); return FALSE; } else { - if (glamor_egl_init(scrn, info->dri2.drm_fd)) { + if (glamor_egl_init(scrn, pRADEONEnt->fd)) { xf86DrvMsg(scrn->scrnIndex, X_INFO, "glamor detected, initialising EGL layer.\n"); } else { diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 691fcdf5..3f14b462 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -187,6 +187,7 @@ static Bool RADEONGetRec(ScrnInfoPtr pScrn) /* Free our private RADEONInfoRec */ static void RADEONFreeRec(ScrnInfoPtr pScrn) { + RADEONEntPtr pRADEONEnt; RADEONInfoPtr info; if (!pScrn || !pScrn->driverPrivate) return; @@ -196,7 +197,9 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn) if (info->fbcon_pixmap) pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap); - if (info->dri2.drm_fd > 0) { + pRADEONEnt = RADEONEntPriv(pScrn); + + if (pRADEONEnt->fd > 0) { DevUnion *pPriv; RADEONEntPtr pRADEONEnt; pPriv = xf86GetEntityPrivate(pScrn->entityList[0], @@ -719,6 +722,7 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) { ScreenPtr screen = dirty->slave_dst->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); xf86CrtcPtr xf86_crtc = radeon_prime_dirty_to_crtc(dirty); drmmode_crtc_private_ptr drmmode_crtc; uintptr_t drm_queue_seq; @@ -748,7 +752,7 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) vbl.request.type |= radeon_populate_vbl_request_type(xf86_crtc); vbl.request.sequence = 1; vbl.request.signal = drm_queue_seq; - if (drmWaitVBlank(RADEONPTR(scrn)->dri2.drm_fd, &vbl)) { + if (drmWaitVBlank(pRADEONEnt->fd, &vbl)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "drmWaitVBlank failed for PRIME update: %s\n", strerror(errno)); @@ -772,9 +776,10 @@ static void radeon_prime_scanout_flip_handler(xf86CrtcPtr crtc, uint32_t msc, uint64_t usec, void *event_data) { + RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = event_data; - drmmode_fb_reference(drmmode_crtc->drmmode->fd, &drmmode_crtc->fb, + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, drmmode_crtc->flip_pending); radeon_prime_scanout_flip_abort(crtc, event_data); } @@ -1012,6 +1017,7 @@ static void radeon_scanout_update(xf86CrtcPtr xf86_crtc) { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(xf86_crtc->scrn); uintptr_t drm_queue_seq; ScrnInfoPtr scrn; drmVBlank vbl; @@ -1056,7 +1062,7 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) vbl.request.type |= radeon_populate_vbl_request_type(xf86_crtc); vbl.request.sequence = 1; vbl.request.signal = drm_queue_seq; - if (drmWaitVBlank(RADEONPTR(scrn)->dri2.drm_fd, &vbl)) { + if (drmWaitVBlank(pRADEONEnt->fd, &vbl)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "drmWaitVBlank failed for scanout update: %s\n", strerror(errno)); @@ -1136,6 +1142,7 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) { SCREEN_PTR(arg); ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int c; @@ -1151,7 +1158,7 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[c]->driver_private; - drmmode_fb_reference(info->drmmode.fd, &drmmode_crtc->fb, NULL); + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL); } return; @@ -1183,7 +1190,7 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) static Bool RADEONIsFastFBWorking(ScrnInfoPtr pScrn) { - RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); struct drm_radeon_info ginfo; int r; uint32_t tmp = 0; @@ -1191,7 +1198,7 @@ static Bool RADEONIsFastFBWorking(ScrnInfoPtr pScrn) memset(&ginfo, 0, sizeof(ginfo)); ginfo.request = RADEON_INFO_FASTFB_WORKING; ginfo.value = (uintptr_t)&tmp; - r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); + r = drmCommandWriteRead(pRADEONEnt->fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); if (r) { return FALSE; } @@ -1202,7 +1209,7 @@ static Bool RADEONIsFastFBWorking(ScrnInfoPtr pScrn) static Bool RADEONIsFusionGARTWorking(ScrnInfoPtr pScrn) { - RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); struct drm_radeon_info ginfo; int r; uint32_t tmp; @@ -1210,7 +1217,7 @@ static Bool RADEONIsFusionGARTWorking(ScrnInfoPtr pScrn) memset(&ginfo, 0, sizeof(ginfo)); ginfo.request = RADEON_INFO_FUSION_GART_WORKING; ginfo.value = (uintptr_t)&tmp; - r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); + r = drmCommandWriteRead(pRADEONEnt->fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); if (r) { return FALSE; } @@ -1221,6 +1228,7 @@ static Bool RADEONIsFusionGARTWorking(ScrnInfoPtr pScrn) static Bool RADEONIsAccelWorking(ScrnInfoPtr pScrn) { + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); struct drm_radeon_info ginfo; int r; @@ -1232,7 +1240,7 @@ static Bool RADEONIsAccelWorking(ScrnInfoPtr pScrn) else ginfo.request = RADEON_INFO_ACCEL_WORKING; ginfo.value = (uintptr_t)&tmp; - r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); + r = drmCommandWriteRead(pRADEONEnt->fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); if (r) { /* If kernel is too old before 2.6.32 than assume accel is working */ if (r == -EINVAL) { @@ -1470,7 +1478,6 @@ static int radeon_get_drm_master_fd(ScrnInfoPtr pScrn) static Bool radeon_open_drm_master(ScrnInfoPtr pScrn) { - RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); drmSetVersion sv; int err; @@ -1478,14 +1485,12 @@ static Bool radeon_open_drm_master(ScrnInfoPtr pScrn) if (pRADEONEnt->fd) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, " reusing fd for second head\n"); - - info->drmmode.fd = info->dri2.drm_fd = pRADEONEnt->fd; pRADEONEnt->fd_ref++; return TRUE; } - info->dri2.drm_fd = radeon_get_drm_master_fd(pScrn); - if (info->dri2.drm_fd == -1) + pRADEONEnt->fd = radeon_get_drm_master_fd(pScrn); + if (pRADEONEnt->fd == -1) return FALSE; /* Check that what we opened was a master or a master-capable FD, @@ -1496,24 +1501,23 @@ static Bool radeon_open_drm_master(ScrnInfoPtr pScrn) sv.drm_di_minor = 1; sv.drm_dd_major = -1; sv.drm_dd_minor = -1; - err = drmSetInterfaceVersion(info->dri2.drm_fd, &sv); + err = drmSetInterfaceVersion(pRADEONEnt->fd, &sv); if (err != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] failed to set drm interface version.\n"); - drmClose(info->dri2.drm_fd); - info->dri2.drm_fd = -1; + drmClose(pRADEONEnt->fd); + pRADEONEnt->fd = -1; return FALSE; } - pRADEONEnt->fd = info->dri2.drm_fd; pRADEONEnt->fd_ref = 1; - info->drmmode.fd = info->dri2.drm_fd; return TRUE; } static Bool r600_get_tile_config(ScrnInfoPtr pScrn) { + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); struct drm_radeon_info ginfo; int r; @@ -1525,7 +1529,7 @@ static Bool r600_get_tile_config(ScrnInfoPtr pScrn) memset(&ginfo, 0, sizeof(ginfo)); ginfo.request = RADEON_INFO_TILING_CONFIG; ginfo.value = (uintptr_t)&tmp; - r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); + r = drmCommandWriteRead(pRADEONEnt->fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); if (r) return FALSE; @@ -1622,6 +1626,7 @@ static Bool r600_get_tile_config(ScrnInfoPtr pScrn) static void RADEONSetupCapabilities(ScrnInfoPtr pScrn) { #ifdef RADEON_PIXMAP_SHARING + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); uint64_t value; int ret; @@ -1632,7 +1637,7 @@ static void RADEONSetupCapabilities(ScrnInfoPtr pScrn) if (info->r600_shadow_fb) return; - ret = drmGetCap(info->dri2.drm_fd, DRM_CAP_PRIME, &value); + ret = drmGetCap(pRADEONEnt->fd, DRM_CAP_PRIME, &value); if (ret == 0) { if (value & DRM_PRIME_CAP_EXPORT) pScrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SourceOffload; @@ -1770,7 +1775,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) info->dri2.available = FALSE; info->dri2.enabled = FALSE; - info->dri2.pKernelDRMVersion = drmGetVersion(info->dri2.drm_fd); + info->dri2.pKernelDRMVersion = drmGetVersion(pRADEONEnt->fd); if (info->dri2.pKernelDRMVersion == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RADEONDRIGetVersion failed to get the DRM version\n"); @@ -1935,7 +1940,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) { struct drm_radeon_gem_info mminfo; - if (!drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo))) + if (!drmCommandWriteRead(pRADEONEnt->fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo))) { info->vram_size = mminfo.vram_visible; info->gart_size = mminfo.gart_size; @@ -2075,10 +2080,7 @@ static Bool RADEONSaveScreen_KMS(ScreenPtr pScreen, int mode) static Bool radeon_set_drm_master(ScrnInfoPtr pScrn) { - RADEONInfoPtr info = RADEONPTR(pScrn); -#ifdef XF86_PDEV_SERVER_FD RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); -#endif int err; #ifdef XF86_PDEV_SERVER_FD @@ -2087,7 +2089,7 @@ static Bool radeon_set_drm_master(ScrnInfoPtr pScrn) return TRUE; #endif - err = drmSetMaster(info->dri2.drm_fd); + err = drmSetMaster(pRADEONEnt->fd); if (err) ErrorF("Unable to retrieve master\n"); @@ -2096,16 +2098,15 @@ static Bool radeon_set_drm_master(ScrnInfoPtr pScrn) static void radeon_drop_drm_master(ScrnInfoPtr pScrn) { - RADEONInfoPtr info = RADEONPTR(pScrn); -#ifdef XF86_PDEV_SERVER_FD RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); +#ifdef XF86_PDEV_SERVER_FD if (pRADEONEnt->platform_dev && (pRADEONEnt->platform_dev->flags & XF86_PDEV_SERVER_FD)) return; #endif - drmDropMaster(info->dri2.drm_fd); + drmDropMaster(pRADEONEnt->fd); } /* Called at the end of each server generation. Restore the original @@ -2177,6 +2178,7 @@ void RADEONFreeScreen_KMS(FREE_SCREEN_ARGS_DECL) Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); int subPixelOrder = SubPixelUnknown; MessageType from; @@ -2201,9 +2203,9 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) if (info->r600_shadow_fb == FALSE) info->directRenderingEnabled = radeon_dri2_screen_init(pScreen); - info->surf_man = radeon_surface_manager_new(info->dri2.drm_fd); + info->surf_man = radeon_surface_manager_new(pRADEONEnt->fd); if (!info->bufmgr) - info->bufmgr = radeon_bo_manager_gem_ctor(info->dri2.drm_fd); + info->bufmgr = radeon_bo_manager_gem_ctor(pRADEONEnt->fd); if (!info->bufmgr) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "failed to initialise GEM buffer manager"); @@ -2212,7 +2214,7 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) drmmode_set_bufmgr(pScrn, &info->drmmode, info->bufmgr); if (!info->csm) - info->csm = radeon_cs_manager_gem_ctor(info->dri2.drm_fd); + info->csm = radeon_cs_manager_gem_ctor(pRADEONEnt->fd); if (!info->csm) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "failed to initialise command submission manager"); diff --git a/src/radeon_present.c b/src/radeon_present.c index 635d1086..e637d786 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -105,10 +105,11 @@ static Bool radeon_present_flush_drm_events(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[0]->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; - struct pollfd p = { .fd = drmmode->fd, .events = POLLIN }; + struct pollfd p = { .fd = pRADEONEnt->fd, .events = POLLIN }; int r; do { @@ -118,7 +119,7 @@ radeon_present_flush_drm_events(ScreenPtr screen) if (r <= 0) return 0; - return drmHandleEvent(drmmode->fd, &drmmode->event_context) >= 0; + return drmHandleEvent(pRADEONEnt->fd, &drmmode->event_context) >= 0; } /* @@ -155,7 +156,7 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) xf86CrtcPtr xf86_crtc = crtc->devPrivate; ScreenPtr screen = crtc->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - RADEONInfoPtr info = RADEONPTR(scrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); int crtc_id = drmmode_get_crtc_id(xf86_crtc); struct radeon_present_vblank_event *event; uintptr_t drm_queue_seq; @@ -180,7 +181,7 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) vbl.request.sequence = msc; vbl.request.signal = drm_queue_seq; for (;;) { - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); + ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); if (!ret) break; if (errno != EBUSY || !radeon_present_flush_drm_events(screen)) { @@ -435,11 +436,11 @@ radeon_present_has_async_flip(ScreenPtr screen) { #ifdef DRM_CAP_ASYNC_PAGE_FLIP ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - RADEONInfoPtr info = RADEONPTR(scrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); int ret; uint64_t value; - ret = drmGetCap(info->dri2.drm_fd, DRM_CAP_ASYNC_PAGE_FLIP, &value); + ret = drmGetCap(pRADEONEnt->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value); if (ret == 0) return value == 1; #endif -- cgit v1.2.3 From aff267ee36cc6a703a532f91f82adc1ba1425ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 14 Mar 2017 16:23:45 +0900 Subject: Use drmmode_crtc->scanout_id instead of 0 to check for scanout buffer Preparation for following change, no functional change intended. Reviewed-by: Alex Deucher --- src/radeon_dri2.c | 5 +++-- src/radeon_kms.c | 4 ++-- src/radeon_present.c | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 435bf539..35fb60d9 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -728,7 +728,8 @@ can_exchange(ScrnInfoPtr pScrn, DrawablePtr draw, drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; if (crtc->enabled && - (crtc->rotatedData || drmmode_crtc->scanout[0].bo)) + (crtc->rotatedData || + drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo)) return FALSE; } @@ -777,7 +778,7 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw, continue; if (!drmmode_crtc || drmmode_crtc->rotate.bo || - drmmode_crtc->scanout[0].bo) + drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo) return FALSE; if (drmmode_crtc->pending_dpms_mode == DPMSModeOn) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 3f14b462..955efc62 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -733,7 +733,7 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) drmmode_crtc = xf86_crtc->driver_private; if (drmmode_crtc->scanout_update_pending || - !drmmode_crtc->scanout[0].pixmap || + !drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap || drmmode_crtc->pending_dpms_mode != DPMSModeOn) return; @@ -1027,7 +1027,7 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) if (!xf86_crtc->enabled || drmmode_crtc->scanout_update_pending || - !drmmode_crtc->scanout[0].pixmap || + !drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap || drmmode_crtc->pending_dpms_mode != DPMSModeOn) return; diff --git a/src/radeon_present.c b/src/radeon_present.c index e637d786..e3a8f7e2 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -249,7 +249,7 @@ radeon_present_check_unflip(ScrnInfoPtr scrn) continue; if (!drmmode_crtc || drmmode_crtc->rotate.bo || - drmmode_crtc->scanout[0].bo) + drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo) return FALSE; if (drmmode_crtc->pending_dpms_mode == DPMSModeOn) -- cgit v1.2.3 From 94dc2b80f3ef0b2c17c20501d824fb0447d52e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 14 Mar 2017 16:57:17 +0900 Subject: If a TearFree flip fails, fall back to non-TearFree operation In order to avoid possible freeze / log file spam in that case. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99769 Reviewed-by: Alex Deucher --- src/drmmode_display.c | 12 +++++++----- src/drmmode_display.h | 2 ++ src/radeon_kms.c | 21 +++++++++++++-------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 4b964b7b..840071fe 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -496,7 +496,7 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) return; } -static void +void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, struct drmmode_scanout *scanout) { @@ -770,15 +770,17 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, ScreenPtr screen = scrn->pScreen; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0], + drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[scanout_id], mode->HDisplay, mode->VDisplay); if (drmmode_crtc->tear_free) { - drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], + drmmode_crtc_scanout_create(crtc, + &drmmode_crtc->scanout[scanout_id ^ 1], mode->HDisplay, mode->VDisplay); } - if (drmmode_crtc->scanout[0].pixmap && - (!drmmode_crtc->tear_free || drmmode_crtc->scanout[1].pixmap)) { + if (drmmode_crtc->scanout[scanout_id].pixmap && + (!drmmode_crtc->tear_free || + drmmode_crtc->scanout[scanout_id ^ 1].pixmap)) { RegionPtr region; BoxPtr box; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index ba1a7bc8..b9bc8fd8 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -192,6 +192,8 @@ extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, extern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode); extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); +extern void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, + struct drmmode_scanout *scanout); extern void drmmode_scanout_free(ScrnInfoPtr scrn); extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 955efc62..b22c9840 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1008,7 +1008,9 @@ static void radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) { - radeon_scanout_do_update(crtc, 0); + drmmode_crtc_private_ptr drmmode_crtc = event_data; + + radeon_scanout_do_update(crtc, drmmode_crtc->scanout_id); radeon_scanout_update_abort(crtc, event_data); } @@ -1027,7 +1029,6 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) if (!xf86_crtc->enabled || drmmode_crtc->scanout_update_pending || - !drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap || drmmode_crtc->pending_dpms_mode != DPMSModeOn) return; @@ -1128,9 +1129,17 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, drmmode_crtc->flip_pending->handle, 0, drm_queue_seq, 0) != 0) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n", + xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s, " + "TearFree inactive until next modeset\n", __func__, strerror(errno)); radeon_drm_abort_entry(drm_queue_seq); + RegionCopy(DamageRegion(drmmode_crtc->scanout_damage), + &drmmode_crtc->scanout_last_region); + RegionEmpty(&drmmode_crtc->scanout_last_region); + radeon_scanout_update(xf86_crtc); + drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, + &drmmode_crtc->scanout[scanout_id]); + drmmode_crtc->tear_free = FALSE; return; } @@ -1172,11 +1181,7 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) if (drmmode_crtc->tear_free) radeon_scanout_flip(pScreen, info, crtc); - else if (info->shadow_primary -#if XF86_CRTC_VERSION >= 4 - || crtc->driverIsPerformingTransform -#endif - ) + else if (drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap) radeon_scanout_update(crtc); } } -- cgit v1.2.3 From 7d7abf99b5441ddb04dbee99bc8fa7abc30d4c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 26 Jul 2017 18:13:35 +0900 Subject: Only handle reflection in the driver with Xorg < 1.16 Xorg doesn't handle the hardware cursor correctly in that case for rotation and general transforms, and we can't force the SW cursor. Fixes: f2bc882f1c10 ("Handle rotation in the driver also with Xorg 1.12-1.18") Reviewed-by: Alex Deucher --- src/drmmode_display.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 840071fe..245a92fb 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -677,10 +677,16 @@ drmmode_handle_transform(xf86CrtcPtr crtc) { Bool ret; +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,903,0) if (crtc->transformPresent || crtc->rotation != RR_Rotate_0) crtc->driverIsPerformingTransform = XF86DriverTransformOutput; else crtc->driverIsPerformingTransform = XF86DriverTransformNone; +#else + crtc->driverIsPerformingTransform = !crtc->transformPresent && + crtc->rotation != RR_Rotate_0 && + (crtc->rotation & 0xf) == RR_Rotate_0; +#endif ret = xf86CrtcRotate(crtc); -- cgit v1.2.3 From e628f604d032d32971a1ca8670469e88939e3de2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 27 Jul 2017 15:24:37 +0900 Subject: Add AC_CONFIG_MACRO_DIRS([m4]) to configure.ac Suggested by one of the tools called by autoreconf. (Cherry picked from amdgpu commit 227b399badaad9bbef0be5a776ce008d0d243449) Acked-by: Alex Deucher --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 700e01a5..c9bc0a95 100644 --- a/configure.ac +++ b/configure.ac @@ -29,6 +29,7 @@ AC_INIT([xf86-video-ati], AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIRS([m4]) AC_CONFIG_AUX_DIR(.) -- cgit v1.2.3 From bf0a759e3bced3a93bead033a26871cc340bd309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 27 Jul 2017 15:26:23 +0900 Subject: Makefile.am: Set ACLOCAL_AMFLAGS = -I m4 Suggested by one of the tools called by autoreconf. (Cherry picked from amdgpu commit 842bad4b951296ca25f47b50cb358e502bf30ebb) Acked-by: Alex Deucher --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index f0e2c3ce..b8d99f32 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,6 +21,8 @@ SUBDIRS = src man conf MAINTAINERCLEANFILES = ChangeLog INSTALL +ACLOCAL_AMFLAGS = -I m4 + .PHONY: ChangeLog INSTALL INSTALL: -- cgit v1.2.3 From 377c9dc7e51cc8ebd06816b08682a8098a49508a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 27 Jul 2017 15:27:54 +0900 Subject: autogen.sh: Pass -f to autoreconf To ensure that any existing copies of autotools files will be replaced with the current versions. (Cherry picked from amdgpu commit a47c0093338d80d84e7033ad15d051925d542ca0) Acked-by: Alex Deucher --- autogen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index a98269f7..49d14c62 100755 --- a/autogen.sh +++ b/autogen.sh @@ -6,7 +6,7 @@ test -z "$srcdir" && srcdir=. ORIGDIR=`pwd` cd "$srcdir" -autoreconf -v --install || exit 1 +autoreconf -f -v --install || exit 1 cd "$ORIGDIR" || exit $? git config --local --get format.subjectPrefix >/dev/null 2>&1 || -- cgit v1.2.3 From c2d26890691ec105858f086b63170ad94c6f7f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 12 Jul 2017 12:13:03 +0900 Subject: Use root window (pixmap) instead of screen pixmap for scanout updates Preparation for following changes, no functional change intended yet. v2: * Add drmmode_screen_damage_destroy callback to prevent use-after-free on server shutdown Reviewed-by: Alex Deucher --- src/drmmode_display.c | 21 ++++++++++++++------- src/radeon_kms.c | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 245a92fb..309ccbd6 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -529,11 +529,8 @@ drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc) &drmmode_crtc->scanout[1]); } - if (drmmode_crtc->scanout_damage) { + if (drmmode_crtc->scanout_damage) DamageDestroy(drmmode_crtc->scanout_damage); - drmmode_crtc->scanout_damage = NULL; - RegionUninit(&drmmode_crtc->scanout_last_region); - } } void @@ -605,6 +602,15 @@ radeon_screen_damage_report(DamagePtr damage, RegionPtr region, void *closure) damage->damage.data = NULL; } +static void +drmmode_screen_damage_destroy(DamagePtr damage, void *closure) +{ + drmmode_crtc_private_ptr drmmode_crtc = closure; + + drmmode_crtc->scanout_damage = NULL; + RegionUninit(&drmmode_crtc->scanout_last_region); +} + static Bool drmmode_can_use_hw_cursor(xf86CrtcPtr crtc) { @@ -793,9 +799,10 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, if (!drmmode_crtc->scanout_damage) { drmmode_crtc->scanout_damage = DamageCreate(radeon_screen_damage_report, - NULL, DamageReportRawRegion, - TRUE, screen, NULL); - DamageRegister(&screen->GetScreenPixmap(screen)->drawable, + drmmode_screen_damage_destroy, + DamageReportRawRegion, + TRUE, screen, drmmode_crtc); + DamageRegister(&screen->root->drawable, drmmode_crtc->scanout_damage); } diff --git a/src/radeon_kms.c b/src/radeon_kms.c index b22c9840..f76d76a9 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -981,7 +981,7 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id) GCPtr gc = GetScratchGC(pDraw->depth, pScreen); ValidateGC(pDraw, gc); - (*gc->ops->CopyArea)(&pScreen->GetScreenPixmap(pScreen)->drawable, + (*gc->ops->CopyArea)(&pScreen->GetWindowPixmap(pScreen->root)->drawable, pDraw, gc, xf86_crtc->x + extents.x1, xf86_crtc->y + extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, -- cgit v1.2.3 From 9bc3eef74452d924f9101c024f66ad9b14c404c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 27 Jul 2017 15:46:41 +0900 Subject: Add drmmode_crtc_can_flip helper To reduce code duplication between DRI2 and Present. No functional change intended yet. Reviewed-by: Alex Deucher --- src/drmmode_display.h | 11 +++++++++++ src/radeon_dri2.c | 5 +---- src/radeon_present.c | 8 +++----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/drmmode_display.h b/src/drmmode_display.h index b9bc8fd8..4378be86 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -139,6 +139,17 @@ enum drmmode_flip_sync { }; +/* Can the page flip ioctl be used for this CRTC? */ +static inline Bool +drmmode_crtc_can_flip(xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + return crtc->enabled && + drmmode_crtc->pending_dpms_mode == DPMSModeOn; +} + + static inline void drmmode_fb_reference_loc(int drm_fd, struct drmmode_fb **old, struct drmmode_fb *new, const char *caller, unsigned line) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 35fb60d9..70751b0b 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -774,14 +774,11 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw, xf86CrtcPtr crtc = config->crtc[i]; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - if (!crtc->enabled) - continue; - if (!drmmode_crtc || drmmode_crtc->rotate.bo || drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo) return FALSE; - if (drmmode_crtc->pending_dpms_mode == DPMSModeOn) + if (drmmode_crtc_can_flip(crtc)) num_crtcs_on++; } diff --git a/src/radeon_present.c b/src/radeon_present.c index e3a8f7e2..85da655d 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -243,16 +243,14 @@ radeon_present_check_unflip(ScrnInfoPtr scrn) return FALSE; for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) { - drmmode_crtc_private_ptr drmmode_crtc = config->crtc[i]->driver_private; - - if (!config->crtc[i]->enabled) - continue; + xf86CrtcPtr crtc = config->crtc[i]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; if (!drmmode_crtc || drmmode_crtc->rotate.bo || drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo) return FALSE; - if (drmmode_crtc->pending_dpms_mode == DPMSModeOn) + if (drmmode_crtc_can_flip(crtc)) num_crtcs_on++; } -- cgit v1.2.3 From 5309bde0c4e28adf2b167191c6d7011a19e31eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 27 Jul 2017 16:11:19 +0900 Subject: Allow DRI page flipping when some CRTCs use separate scanout buffers As long as the CRTC we're synchronizing to doesn't. v2: * Remove redundant checks from can_exchange which still prevented DRI2 page flipping Reviewed-by: Alex Deucher --- man/radeon.man | 2 +- src/drmmode_display.c | 2 +- src/drmmode_display.h | 4 +++- src/radeon_dri2.c | 30 +++++++----------------------- src/radeon_present.c | 12 ++++-------- 5 files changed, 16 insertions(+), 34 deletions(-) diff --git a/man/radeon.man b/man/radeon.man index 3e1723f2..1e9a7beb 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -285,7 +285,7 @@ Set the default value of the per-output 'TearFree' property, which controls tearing prevention using the hardware page flipping mechanism. TearFree is on for any CRTC associated with one or more outputs with TearFree on. Two separate scanout buffers need to be allocated for each CRTC with TearFree -on. While TearFree is on for any CRTC, it currently prevents clients from using +on. While TearFree is on for any CRTC, it may prevent clients from using DRI page flipping. If this option is set, the default value of the property is 'on' or 'off' accordingly. If this option isn't set, the default value of the property is diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 309ccbd6..03b8a482 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -3014,7 +3014,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, for (i = 0; i < config->num_crtc; i++) { crtc = config->crtc[i]; - if (!crtc->enabled) + if (!drmmode_crtc_can_flip(crtc)) continue; flipdata->flip_count++; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 4378be86..f859377c 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -146,7 +146,9 @@ drmmode_crtc_can_flip(xf86CrtcPtr crtc) drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; return crtc->enabled && - drmmode_crtc->pending_dpms_mode == DPMSModeOn; + drmmode_crtc->pending_dpms_mode == DPMSModeOn && + !drmmode_crtc->rotate.bo && + !drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo; } diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 70751b0b..4b059897 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -720,18 +720,6 @@ can_exchange(ScrnInfoPtr pScrn, DrawablePtr draw, struct dri2_buffer_priv *back_priv = back->driverPrivate; PixmapPtr front_pixmap; PixmapPtr back_pixmap = back_priv->pixmap; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; - - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - - if (crtc->enabled && - (crtc->rotatedData || - drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo)) - return FALSE; - } if (!update_front(draw, front)) return FALSE; @@ -754,9 +742,10 @@ can_exchange(ScrnInfoPtr pScrn, DrawablePtr draw, } static Bool -can_flip(ScrnInfoPtr pScrn, DrawablePtr draw, +can_flip(xf86CrtcPtr crtc, DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back) { + ScrnInfoPtr pScrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); int num_crtcs_on; @@ -771,15 +760,10 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw, return FALSE; for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) { - xf86CrtcPtr crtc = config->crtc[i]; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - - if (!drmmode_crtc || drmmode_crtc->rotate.bo || - drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo) - return FALSE; - - if (drmmode_crtc_can_flip(crtc)) + if (drmmode_crtc_can_flip(config->crtc[i])) num_crtcs_on++; + else if (config->crtc[i] == crtc) + return FALSE; } return num_crtcs_on > 0 && can_exchange(pScrn, draw, front, back); @@ -859,7 +843,7 @@ static void radeon_dri2_frame_event_handler(xf86CrtcPtr crtc, uint32_t seq, switch (event->type) { case DRI2_FLIP: - if (can_flip(scrn, drawable, event->front, event->back) && + if (can_flip(crtc, drawable, event->front, event->back) && radeon_dri2_schedule_flip(crtc, event->client, drawable, @@ -1352,7 +1336,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, current_msc &= 0xffffffff; /* Flips need to be submitted one frame before */ - if (can_flip(scrn, draw, front, back)) { + if (can_flip(crtc, draw, front, back)) { swap_info->type = DRI2_FLIP; flip = 1; } diff --git a/src/radeon_present.c b/src/radeon_present.c index 85da655d..4d43733e 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -243,14 +243,7 @@ radeon_present_check_unflip(ScrnInfoPtr scrn) return FALSE; for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) { - xf86CrtcPtr crtc = config->crtc[i]; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - - if (!drmmode_crtc || drmmode_crtc->rotate.bo || - drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo) - return FALSE; - - if (drmmode_crtc_can_flip(crtc)) + if (drmmode_crtc_can_flip(config->crtc[i])) num_crtcs_on++; } @@ -286,6 +279,9 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, radeon_present_get_pixmap_tiling_flags(info, screen_pixmap)) return FALSE; + if (!drmmode_crtc_can_flip(crtc->devPrivate)) + return FALSE; + return radeon_present_check_unflip(scrn); } -- cgit v1.2.3 From 01b040b4a80754b8c8a305cbe968416182b54246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 15 Aug 2017 17:15:27 +0900 Subject: Adapt to PixmapDirtyUpdateRec::src being a DrawablePtr --- src/drmmode_display.c | 10 +++++++--- src/radeon.h | 26 ++++++++++++++++++++++++++ src/radeon_kms.c | 20 ++++++++++---------- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 03b8a482..addee9ca 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -745,7 +745,7 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { - if (dirty->src == drmmode_crtc->prime_scanout_pixmap) { + if (radeon_dirty_src_equals(dirty, drmmode_crtc->prime_scanout_pixmap)) { dirty->slave_dst = drmmode_crtc->scanout[scanout_id].pixmap; break; @@ -1294,7 +1294,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) PixmapDirtyUpdatePtr dirty; xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { - if (dirty->src == drmmode_crtc->prime_scanout_pixmap) { + if (radeon_dirty_src_equals(dirty, drmmode_crtc->prime_scanout_pixmap)) { PixmapStopDirtyTracking(dirty->src, dirty->slave_dst); break; } @@ -1321,7 +1321,11 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) drmmode_crtc->prime_scanout_pixmap = ppix; -#ifdef HAS_DIRTYTRACKING_ROTATION +#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC + PixmapStartDirtyTracking(&ppix->drawable, + drmmode_crtc->scanout[scanout_id].pixmap, + 0, 0, 0, 0, RR_Rotate_0); +#elif defined(HAS_DIRTYTRACKING_ROTATION) PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[scanout_id].pixmap, 0, 0, 0, 0, RR_Rotate_0); #elif defined(HAS_DIRTYTRACKING2) diff --git a/src/radeon.h b/src/radeon.h index ca509561..d815d3f0 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -184,6 +184,32 @@ typedef enum { #define RADEON_PIXMAP_SHARING 1 #define radeon_is_gpu_screen(screen) (screen)->isGPU #define radeon_is_gpu_scrn(scrn) (scrn)->is_gpu + +static inline ScreenPtr +radeon_dirty_master(PixmapDirtyUpdatePtr dirty) +{ +#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC + ScreenPtr screen = dirty->src->pScreen; +#else + ScreenPtr screen = dirty->src->drawable.pScreen; +#endif + + if (screen->current_master) + return screen->current_master; + + return screen; +} + +static inline Bool +radeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap) +{ +#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC + return dirty->src == &pixmap->drawable; +#else + return dirty->src == pixmap; +#endif +} + #else #define radeon_is_gpu_screen(screen) 0 #define radeon_is_gpu_scrn(scrn) 0 diff --git a/src/radeon_kms.c b/src/radeon_kms.c index f76d76a9..5ae94f5c 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -546,7 +546,7 @@ dirty_region(PixmapDirtyUpdatePtr dirty) static void redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region) { - ScrnInfoPtr pScrn = xf86ScreenToScrn(dirty->src->drawable.pScreen); + ScrnInfoPtr pScrn = xf86ScreenToScrn(dirty->slave_dst->drawable.pScreen); if (RegionNil(region)) goto out; @@ -579,12 +579,12 @@ radeon_prime_scanout_update_abort(xf86CrtcPtr crtc, void *event_data) void radeon_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) { - ScreenPtr master_screen = dirty->src->master_pixmap->drawable.pScreen; + ScreenPtr master_screen = radeon_dirty_master(dirty); PixmapDirtyUpdatePtr ent; RegionPtr region; xorg_list_for_each_entry(ent, &master_screen->pixmap_dirty_list, ent) { - if (ent->slave_dst != dirty->src) + if (!radeon_dirty_src_equals(dirty, ent->slave_dst)) continue; region = dirty_region(ent); @@ -599,7 +599,7 @@ radeon_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) static Bool master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) { - ScreenPtr master_screen = dirty->src->master_pixmap->drawable.pScreen; + ScreenPtr master_screen = radeon_dirty_master(dirty); return master_screen->SyncSharedPixmap != NULL; } @@ -615,7 +615,7 @@ slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) static void call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) { - ScreenPtr master_screen = dirty->src->master_pixmap->drawable.pScreen; + ScreenPtr master_screen = radeon_dirty_master(dirty); master_screen->SyncSharedPixmap(dirty); } @@ -625,7 +625,7 @@ call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) static Bool master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) { - ScrnInfoPtr master_scrn = xf86ScreenToScrn(dirty->src->master_pixmap->drawable.pScreen); + ScrnInfoPtr master_scrn = xf86ScreenToScrn(radeon_dirty_master(dirty)); return master_scrn->driverName == scrn->driverName; } @@ -660,7 +660,7 @@ radeon_prime_dirty_to_crtc(PixmapDirtyUpdatePtr dirty) xf86CrtcPtr xf86_crtc = xf86_config->crtc[c]; drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; - if (drmmode_crtc->prime_scanout_pixmap == dirty->src) + if (radeon_dirty_src_equals(dirty, drmmode_crtc->prime_scanout_pixmap)) return xf86_crtc; } @@ -677,7 +677,7 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id) Bool ret = FALSE; xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { - if (dirty->src == drmmode_crtc->prime_scanout_pixmap) { + if (radeon_dirty_src_equals(dirty, drmmode_crtc->prime_scanout_pixmap)) { RegionPtr region; if (master_has_sync_shared_pixmap(scrn, dirty)) @@ -854,10 +854,10 @@ radeon_dirty_update(ScrnInfoPtr scrn) PixmapDirtyUpdatePtr region_ent = ent; if (master_has_sync_shared_pixmap(scrn, ent)) { - ScreenPtr master_screen = ent->src->master_pixmap->drawable.pScreen; + ScreenPtr master_screen = radeon_dirty_master(ent); xorg_list_for_each_entry(region_ent, &master_screen->pixmap_dirty_list, ent) { - if (region_ent->slave_dst == ent->src) + if (radeon_dirty_src_equals(ent, region_ent->slave_dst)) break; } } -- cgit v1.2.3 From 3f120fa1d5d921656a367751bc079e020e9ab105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 3 Aug 2017 17:42:51 +0900 Subject: Remove drmmode_crtc->scanout_destroy[] array No longer necessary since we're reference counting framebuffers. Reviewed-by: Alex Deucher flip_pending) { - drmmode_crtc->scanout_destroy[0] = drmmode_crtc->scanout[0]; - drmmode_crtc->scanout[0].pixmap = NULL; - drmmode_crtc->scanout[0].bo = NULL; - drmmode_crtc->scanout_destroy[1] = drmmode_crtc->scanout[1]; - drmmode_crtc->scanout[1].pixmap = NULL; - drmmode_crtc->scanout[1].bo = NULL; - } else { - drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, - &drmmode_crtc->scanout[0]); - drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, - &drmmode_crtc->scanout[1]); - } + drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, + &drmmode_crtc->scanout[0]); + drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, + &drmmode_crtc->scanout[1]); if (drmmode_crtc->scanout_damage) DamageDestroy(drmmode_crtc->scanout_damage); @@ -2414,11 +2405,6 @@ drmmode_clear_pending_flip(xf86CrtcPtr crtc) drmmode_crtc_dpms(crtc, drmmode_crtc->pending_dpms_mode); } - - drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, - &drmmode_crtc->scanout_destroy[0]); - drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, - &drmmode_crtc->scanout_destroy[1]); } static void diff --git a/src/drmmode_display.h b/src/drmmode_display.h index f859377c..82dcff0e 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -83,7 +83,6 @@ typedef struct { struct radeon_bo *cursor_bo; struct drmmode_scanout rotate; struct drmmode_scanout scanout[2]; - struct drmmode_scanout scanout_destroy[2]; DamagePtr scanout_damage; RegionRec scanout_last_region; unsigned scanout_id; -- cgit v1.2.3 From 49cc61ab970ee28d4509b4e2dd0a57165136889f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 1 Aug 2017 18:45:53 +0900 Subject: Pass reference CRTC to radeon_do_pageflip directly Simplifies the code slightly. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 11 +++-------- src/drmmode_display.h | 2 +- src/radeon_dri2.c | 4 +--- src/radeon_present.c | 6 ++---- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 53314846..46a579ff 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2959,7 +2959,7 @@ void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode) Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, PixmapPtr new_front, uint64_t id, void *data, - int ref_crtc_hw_id, radeon_drm_handler_proc handler, + xf86CrtcPtr ref_crtc, radeon_drm_handler_proc handler, radeon_drm_abort_proc abort, enum drmmode_flip_sync flip_sync, uint32_t target_msc) @@ -3000,6 +3000,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, flipdata->event_data = data; flipdata->handler = handler; flipdata->abort = abort; + flipdata->fe_crtc = ref_crtc; for (i = 0; i < config->num_crtc; i++) { crtc = config->crtc[i]; @@ -3010,12 +3011,6 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, flipdata->flip_count++; drmmode_crtc = crtc->driver_private; - /* Only the reference crtc will finally deliver its page flip - * completion event. All other crtc's events will be discarded. - */ - if (drmmode_crtc->hw_id == ref_crtc_hw_id) - flipdata->fe_crtc = crtc; - drm_queue_seq = radeon_drm_queue_alloc(crtc, client, id, flipdata, drmmode_flip_handler, @@ -3026,7 +3021,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, goto error; } - if (drmmode_crtc->hw_id == ref_crtc_hw_id) { + if (crtc == ref_crtc) { if (drmmode_page_flip_target_absolute(pRADEONEnt, drmmode_crtc, fb->handle, diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 82dcff0e..f2104789 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -219,7 +219,7 @@ extern void drmmode_clear_pending_flip(xf86CrtcPtr crtc); Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, PixmapPtr new_front, uint64_t id, void *data, - int ref_crtc_hw_id, radeon_drm_handler_proc handler, + xf86CrtcPtr ref_crtc, radeon_drm_handler_proc handler, radeon_drm_abort_proc abort, enum drmmode_flip_sync flip_sync, uint32_t target_msc); diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 4b059897..80b17f1f 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -654,7 +654,6 @@ radeon_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client, RADEONInfoPtr info = RADEONPTR(scrn); struct dri2_buffer_priv *back_priv; DRI2FrameEventPtr flip_info; - int ref_crtc_hw_id = drmmode_get_crtc_id(crtc); flip_info = calloc(1, sizeof(DRI2FrameEventRec)); if (!flip_info) @@ -674,8 +673,7 @@ radeon_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client, /* Page flip the full screen buffer */ back_priv = back->driverPrivate; if (radeon_do_pageflip(scrn, client, back_priv->pixmap, - RADEON_DRM_QUEUE_ID_DEFAULT, flip_info, - ref_crtc_hw_id, + RADEON_DRM_QUEUE_ID_DEFAULT, flip_info, crtc, radeon_dri2_flip_event_handler, radeon_dri2_flip_event_abort, FLIP_VSYNC, target_msc - radeon_get_msc_delta(draw, crtc))) { diff --git a/src/radeon_present.c b/src/radeon_present.c index 4d43733e..c01ba95f 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -325,8 +325,6 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, ScrnInfoPtr scrn = xf86ScreenToScrn(screen); RADEONInfoPtr info = RADEONPTR(scrn); struct radeon_present_vblank_event *event; - xf86CrtcPtr xf86_crtc = crtc->devPrivate; - int crtc_id = xf86_crtc ? drmmode_get_crtc_id(xf86_crtc) : -1; Bool ret; if (!radeon_present_check_flip(crtc, screen->root, pixmap, sync_flip)) @@ -341,7 +339,7 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, radeon_cs_flush_indirect(scrn); ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, pixmap, - event_id, event, crtc_id, + event_id, event, crtc->devPrivate, radeon_present_flip_event, radeon_present_flip_abort, sync_flip ? FLIP_VSYNC : FLIP_ASYNC, @@ -385,7 +383,7 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) event->unflip = TRUE; if (radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, pixmap, - event_id, event, -1, radeon_present_flip_event, + event_id, event, NULL, radeon_present_flip_event, radeon_present_flip_abort, flip_sync, 0)) return; -- cgit v1.2.3 From 99f1d7a474af3683fe1a66f50c0bb8935478ff0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 14 Aug 2017 12:23:04 +0900 Subject: Create drmmode_wait_vblank helper Allows cleaning up the code considerably. v2: * Fix "drmWaiVBlank" typo, add blank line for readability (Slava Abramov) * Rename in/out sequence parameters to "target_seq" and "result_seq", hopefully that will be clearer. Reviewed-by: Alex Deucher # v1 --- src/drmmode_display.c | 63 ++++++++++++++++++++---------- src/drmmode_display.h | 5 +++ src/radeon.h | 2 - src/radeon_dri2.c | 103 ++++++++++++++------------------------------------ src/radeon_kms.c | 22 +++-------- src/radeon_present.c | 23 ++--------- 6 files changed, 85 insertions(+), 133 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 46a579ff..d86f8300 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -242,6 +242,41 @@ drmmode_ConvertToKMode(ScrnInfoPtr scrn, } +/* + * Utility helper for drmWaitVBlank + */ +Bool +drmmode_wait_vblank(xf86CrtcPtr crtc, drmVBlankSeqType type, + uint32_t target_seq, unsigned long signal, uint64_t *ust, + uint32_t *result_seq) +{ + int crtc_id = drmmode_get_crtc_id(crtc); + ScrnInfoPtr scrn = crtc->scrn; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + drmVBlank vbl; + + if (crtc_id == 1) + type |= DRM_VBLANK_SECONDARY; + else if (crtc_id > 1) + type |= (crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK; + + vbl.request.type = type; + vbl.request.sequence = target_seq; + vbl.request.signal = signal; + + if (drmWaitVBlank(pRADEONEnt->fd, &vbl) != 0) + return FALSE; + + if (ust) + *ust = (uint64_t)vbl.reply.tval_sec * 1000000 + + vbl.reply.tval_usec; + if (result_seq) + *result_seq = vbl.reply.sequence; + + return TRUE; +} + /* * Retrieves present time in microseconds that is compatible * with units used by vblank timestamps. Depending on the kernel @@ -272,23 +307,15 @@ int drmmode_get_current_ust(int drm_fd, CARD64 *ust) int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc) { ScrnInfoPtr scrn = crtc->scrn; - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - drmVBlank vbl; - int ret; - - vbl.request.type = DRM_VBLANK_RELATIVE; - vbl.request.type |= radeon_populate_vbl_request_type(crtc); - vbl.request.sequence = 0; + uint32_t seq; - ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); - if (ret) { + if (!drmmode_wait_vblank(crtc, DRM_VBLANK_RELATIVE, 0, 0, ust, &seq)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "get vblank counter failed: %s\n", strerror(errno)); - return ret; + return -1; } - *ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec; - *msc = vbl.reply.sequence; + *msc = seq; return Success; } @@ -305,7 +332,7 @@ drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode) drmmode_crtc->pending_dpms_mode = mode; if (drmmode_crtc->dpms_mode == DPMSModeOn && mode != DPMSModeOn) { - drmVBlank vbl; + uint32_t seq; /* Wait for any pending flip to finish */ if (drmmode_crtc->flip_pending) @@ -315,20 +342,14 @@ drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode) * On->Off transition: record the last vblank time, * sequence number and frame period. */ - vbl.request.type = DRM_VBLANK_RELATIVE; - vbl.request.type |= radeon_populate_vbl_request_type(crtc); - vbl.request.sequence = 0; - ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); - if (ret) + if (!drmmode_wait_vblank(crtc, DRM_VBLANK_RELATIVE, 0, 0, &ust, + &seq)) xf86DrvMsg(scrn->scrnIndex, X_ERROR, "%s cannot get last vblank counter\n", __func__); else { - CARD64 seq = (CARD64)vbl.reply.sequence; CARD64 nominal_frame_rate, pix_in_frame; - ust = ((CARD64)vbl.reply.tval_sec * 1000000) + - vbl.reply.tval_usec; drmmode_crtc->dpms_last_ust = ust; drmmode_crtc->dpms_last_seq = seq; nominal_frame_rate = crtc->mode.Clock; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index f2104789..71d1c4a4 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -226,5 +226,10 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc); int drmmode_get_current_ust(int drm_fd, CARD64 *ust); +Bool drmmode_wait_vblank(xf86CrtcPtr crtc, drmVBlankSeqType type, + uint32_t target_seq, unsigned long signal, + uint64_t *ust, uint32_t *result_seq); + + #endif diff --git a/src/radeon.h b/src/radeon.h index d815d3f0..b93e2816 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -693,8 +693,6 @@ extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn, void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size); extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn); -drmVBlankSeqType radeon_populate_vbl_request_type(xf86CrtcPtr crtc); - static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix) { #ifdef USE_GLAMOR diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 80b17f1f..a0deb6ba 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -889,26 +889,6 @@ cleanup: radeon_dri2_frame_event_abort(crtc, event_data); } -drmVBlankSeqType radeon_populate_vbl_request_type(xf86CrtcPtr crtc) -{ - drmVBlankSeqType type = 0; - int crtc_id = drmmode_get_crtc_id(crtc); - - if (crtc_id == 1) - type |= DRM_VBLANK_SECONDARY; - else if (crtc_id > 1) -#ifdef DRM_VBLANK_HIGH_CRTC_SHIFT - type |= (crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT) & - DRM_VBLANK_HIGH_CRTC_MASK; -#else - ErrorF("radeon driver bug: %s called for CRTC %d > 1, but " - "DRM_VBLANK_HIGH_CRTC_MASK not defined at build time\n", - __func__, crtc_id); -#endif - - return type; -} - /* * This function should be called on a disabled CRTC only (i.e., CRTC * in DPMS-off state). It will calculate the delay necessary to reach @@ -1087,13 +1067,11 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, { ScreenPtr screen = draw->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); DRI2FrameEventPtr wait_info = NULL; uintptr_t drm_queue_seq = 0; xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE); uint32_t msc_delta; - drmVBlank vbl; - int ret; + uint32_t seq; CARD64 current_msc; /* Truncate to match kernel interfaces; means occasional overflow @@ -1132,17 +1110,13 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, } /* Get current count */ - vbl.request.type = DRM_VBLANK_RELATIVE; - vbl.request.type |= radeon_populate_vbl_request_type(crtc); - vbl.request.sequence = 0; - ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); - if (ret) { + if (!drmmode_wait_vblank(crtc, DRM_VBLANK_RELATIVE, 0, 0, NULL, &seq)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "get vblank counter failed: %s\n", strerror(errno)); goto out_complete; } - current_msc = vbl.reply.sequence + msc_delta; + current_msc = seq + msc_delta; current_msc &= 0xffffffff; drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT, @@ -1169,12 +1143,9 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, */ if (current_msc >= target_msc) target_msc = current_msc; - vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; - vbl.request.type |= radeon_populate_vbl_request_type(crtc); - vbl.request.sequence = target_msc - msc_delta; - vbl.request.signal = drm_queue_seq; - ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); - if (ret) { + if (!drmmode_wait_vblank(crtc, DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT, + target_msc - msc_delta, drm_queue_seq, NULL, + NULL)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "get vblank counter failed: %s\n", strerror(errno)); goto out_complete; @@ -1188,11 +1159,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, * If we get here, target_msc has already passed or we don't have one, * so we queue an event that will satisfy the divisor/remainder equation. */ - vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; - vbl.request.type |= radeon_populate_vbl_request_type(crtc); - - vbl.request.sequence = current_msc - (current_msc % divisor) + - remainder - msc_delta; + target_msc = current_msc - (current_msc % divisor) + remainder - msc_delta; /* * If calculated remainder is larger than requested remainder, @@ -1201,11 +1168,10 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, * that will happen. */ if ((current_msc % divisor) >= remainder) - vbl.request.sequence += divisor; + target_msc += divisor; - vbl.request.signal = drm_queue_seq; - ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); - if (ret) { + if (!drmmode_wait_vblank(crtc, DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT, + target_msc, drm_queue_seq, NULL, NULL)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "get vblank counter failed: %s\n", strerror(errno)); goto out_complete; @@ -1249,14 +1215,14 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, { ScreenPtr screen = draw->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE); uint32_t msc_delta; - drmVBlank vbl; - int ret, flip = 0; + drmVBlankSeqType type; + uint32_t seq; + int flip = 0; DRI2FrameEventPtr swap_info = NULL; uintptr_t drm_queue_seq; - CARD64 current_msc; + CARD64 current_msc, event_msc; BoxRec box; RegionRec region; @@ -1319,18 +1285,14 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, } /* Get current count */ - vbl.request.type = DRM_VBLANK_RELATIVE; - vbl.request.type |= radeon_populate_vbl_request_type(crtc); - vbl.request.sequence = 0; - ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); - if (ret) { + if (!drmmode_wait_vblank(crtc, DRM_VBLANK_RELATIVE, 0, 0, NULL, &seq)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "first get vblank counter failed: %s\n", strerror(errno)); goto blit_fallback; } - current_msc = vbl.reply.sequence + msc_delta; + current_msc = seq + msc_delta; current_msc &= 0xffffffff; /* Flips need to be submitted one frame before */ @@ -1352,14 +1314,13 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, * the swap. */ if (divisor == 0 || current_msc < *target_msc) { - vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; + type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; /* If non-pageflipping, but blitting/exchanging, we need to use * DRM_VBLANK_NEXTONMISS to avoid unreliable timestamping later * on. */ if (flip == 0) - vbl.request.type |= DRM_VBLANK_NEXTONMISS; - vbl.request.type |= radeon_populate_vbl_request_type(crtc); + type |= DRM_VBLANK_NEXTONMISS; /* If target_msc already reached or passed, set it to * current_msc to ensure we return a reasonable value back @@ -1368,17 +1329,15 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, if (current_msc >= *target_msc) *target_msc = current_msc; - vbl.request.sequence = *target_msc - msc_delta; - vbl.request.signal = drm_queue_seq; - ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); - if (ret) { + if (!drmmode_wait_vblank(crtc, type, *target_msc - msc_delta, + drm_queue_seq, NULL, &seq)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "divisor 0 get vblank counter failed: %s\n", strerror(errno)); goto blit_fallback; } - *target_msc = vbl.reply.sequence + flip + msc_delta; + *target_msc = seq + flip + msc_delta; swap_info->frame = *target_msc; return TRUE; @@ -1389,13 +1348,11 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, * and we need to queue an event that will satisfy the divisor/remainder * equation. */ - vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; + type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; if (flip == 0) - vbl.request.type |= DRM_VBLANK_NEXTONMISS; - vbl.request.type |= radeon_populate_vbl_request_type(crtc); + type |= DRM_VBLANK_NEXTONMISS; - vbl.request.sequence = current_msc - (current_msc % divisor) + - remainder - msc_delta; + event_msc = current_msc - (current_msc % divisor) + remainder - msc_delta; /* * If the calculated deadline vbl.request.sequence is smaller than @@ -1408,15 +1365,13 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, * into account, as well as a potential DRM_VBLANK_NEXTONMISS delay * if we are blitting/exchanging instead of flipping. */ - if (vbl.request.sequence <= current_msc) - vbl.request.sequence += divisor; + if (event_msc <= current_msc) + event_msc += divisor; /* Account for 1 frame extra pageflip delay if flip > 0 */ - vbl.request.sequence -= flip; + event_msc -= flip; - vbl.request.signal = drm_queue_seq; - ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); - if (ret) { + if (!drmmode_wait_vblank(crtc, type, event_msc, drm_queue_seq, NULL, &seq)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "final get vblank counter failed: %s\n", strerror(errno)); @@ -1424,7 +1379,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, } /* Adjust returned value for 1 fame pageflip offset of flip > 0 */ - *target_msc = vbl.reply.sequence + flip + msc_delta; + *target_msc = seq + flip + msc_delta; *target_msc &= 0xffffffff; swap_info->frame = *target_msc; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 5ae94f5c..423d36cb 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -722,11 +722,9 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) { ScreenPtr screen = dirty->slave_dst->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); xf86CrtcPtr xf86_crtc = radeon_prime_dirty_to_crtc(dirty); drmmode_crtc_private_ptr drmmode_crtc; uintptr_t drm_queue_seq; - drmVBlank vbl; if (!xf86_crtc || !xf86_crtc->enabled) return; @@ -748,13 +746,10 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) return; } - vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT; - vbl.request.type |= radeon_populate_vbl_request_type(xf86_crtc); - vbl.request.sequence = 1; - vbl.request.signal = drm_queue_seq; - if (drmWaitVBlank(pRADEONEnt->fd, &vbl)) { + if (!drmmode_wait_vblank(xf86_crtc, DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT, + 1, drm_queue_seq, NULL, NULL)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "drmWaitVBlank failed for PRIME update: %s\n", + "drmmode_wait_vblank failed for PRIME update: %s\n", strerror(errno)); radeon_drm_abort_entry(drm_queue_seq); return; @@ -1019,10 +1014,8 @@ static void radeon_scanout_update(xf86CrtcPtr xf86_crtc) { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; - RADEONEntPtr pRADEONEnt = RADEONEntPriv(xf86_crtc->scrn); uintptr_t drm_queue_seq; ScrnInfoPtr scrn; - drmVBlank vbl; DamagePtr pDamage; RegionPtr pRegion; BoxRec extents; @@ -1059,13 +1052,10 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) return; } - vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT; - vbl.request.type |= radeon_populate_vbl_request_type(xf86_crtc); - vbl.request.sequence = 1; - vbl.request.signal = drm_queue_seq; - if (drmWaitVBlank(pRADEONEnt->fd, &vbl)) { + if (!drmmode_wait_vblank(xf86_crtc, DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT, + 1, drm_queue_seq, NULL, NULL)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "drmWaitVBlank failed for scanout update: %s\n", + "drmmode_wait_vblank failed for scanout update: %s\n", strerror(errno)); radeon_drm_abort_entry(drm_queue_seq); return; diff --git a/src/radeon_present.c b/src/radeon_present.c index c01ba95f..135a0a97 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -55,16 +55,6 @@ struct radeon_present_vblank_event { Bool unflip; }; -static uint32_t crtc_select(int crtc_id) -{ - if (crtc_id > 1) - return crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT; - else if (crtc_id > 0) - return DRM_VBLANK_SECONDARY; - else - return 0; -} - static RRCrtcPtr radeon_present_get_crtc(WindowPtr window) { @@ -155,13 +145,8 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) { xf86CrtcPtr xf86_crtc = crtc->devPrivate; ScreenPtr screen = crtc->pScreen; - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - int crtc_id = drmmode_get_crtc_id(xf86_crtc); struct radeon_present_vblank_event *event; uintptr_t drm_queue_seq; - drmVBlank vbl; - int ret; event = calloc(sizeof(struct radeon_present_vblank_event), 1); if (!event) @@ -177,12 +162,10 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) return BadAlloc; } - vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | crtc_select(crtc_id); - vbl.request.sequence = msc; - vbl.request.signal = drm_queue_seq; for (;;) { - ret = drmWaitVBlank(pRADEONEnt->fd, &vbl); - if (!ret) + if (drmmode_wait_vblank(xf86_crtc, + DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT, msc, + drm_queue_seq, NULL, NULL)) break; if (errno != EBUSY || !radeon_present_flush_drm_events(screen)) { radeon_drm_abort_entry(drm_queue_seq); -- cgit v1.2.3 From f87acdbfb1b0b6d2769764772a52ea8b81675e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 28 Jul 2017 12:28:53 +0900 Subject: Create drmmode_crtc_wait_pending_event helper macro Preparation for following change, no functional change intended yet. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index d86f8300..45e04058 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -99,6 +99,14 @@ RADEONZaphodStringMatches(ScrnInfoPtr pScrn, const char *s, char *output_name) return FALSE; } + +/* Wait for the boolean condition to be FALSE */ +#define drmmode_crtc_wait_pending_event(drmmode_crtc, fd, condition) \ + do {} while ((condition) && \ + drmHandleEvent(fd, &drmmode_crtc->drmmode->event_context) \ + > 0); + + static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, int width, int height, int depth, int bpp, @@ -951,10 +959,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, goto done; } - /* Wait for any pending flip to finish */ - do {} while (drmmode_crtc->flip_pending && - drmHandleEvent(pRADEONEnt->fd, - &drmmode->event_context) > 0); + drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, + drmmode_crtc->flip_pending); if (drmModeSetCrtc(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, -- cgit v1.2.3 From e6d7dc2070f4d21a6900916bb70a31839112882c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 3 Aug 2017 17:51:20 +0900 Subject: Wait for pending flips synchronously before turning off a CRTC Allows removing drmmode_clear_pending_flip and the pending_dpms_mode field and cleaning up the code considerably. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 60 ++++++++++----------------------------------------- src/drmmode_display.h | 5 +---- src/radeon_kms.c | 12 ++++++----- src/radeon_present.c | 2 +- src/radeon_video.c | 2 +- 5 files changed, 21 insertions(+), 60 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 45e04058..2692f697 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -337,14 +337,11 @@ drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode) CARD64 ust; int ret; - drmmode_crtc->pending_dpms_mode = mode; - if (drmmode_crtc->dpms_mode == DPMSModeOn && mode != DPMSModeOn) { uint32_t seq; - /* Wait for any pending flip to finish */ - if (drmmode_crtc->flip_pending) - return; + drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, + drmmode_crtc->flip_pending); /* * On->Off transition: record the last vblank time, @@ -398,10 +395,8 @@ drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) /* Disable unused CRTCs */ if (!crtc->enabled || mode != DPMSModeOn) { - /* Wait for any pending flip to finish */ - if (drmmode_crtc->flip_pending) - return; - + drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, + drmmode_crtc->flip_pending); drmModeSetCrtc(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 0, 0, NULL, 0, NULL); drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL); @@ -1419,7 +1414,6 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res drmmode_crtc->mode_crtc = drmModeGetCrtc(pRADEONEnt->fd, mode_res->crtcs[num]); drmmode_crtc->drmmode = drmmode; drmmode_crtc->dpms_mode = DPMSModeOff; - drmmode_crtc->pending_dpms_mode = DPMSModeOff; crtc->driver_private = drmmode_crtc; drmmode_crtc_hw_id(crtc); @@ -1545,16 +1539,9 @@ drmmode_output_dpms(xf86OutputPtr output, int mode) if (!koutput) return; - if (mode != DPMSModeOn && crtc) { - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - + if (mode != DPMSModeOn && crtc) drmmode_do_crtc_dpms(crtc, mode); - /* Wait for any pending flip to finish */ - if (drmmode_crtc->flip_pending) - return; - } - drmModeConnectorSetProperty(pRADEONEnt->fd, koutput->connector_id, drmmode_output->dpms_enum_id, mode); @@ -2405,38 +2392,11 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { drmmode_xf86crtc_resize }; -void -drmmode_clear_pending_flip(xf86CrtcPtr crtc) -{ - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - ScrnInfoPtr scrn = crtc->scrn; - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, - NULL); - - if (!crtc->enabled || - (drmmode_crtc->pending_dpms_mode != DPMSModeOn && - drmmode_crtc->dpms_mode != drmmode_crtc->pending_dpms_mode)) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); - int o; - - for (o = 0; o < xf86_config->num_output; o++) { - xf86OutputPtr output = xf86_config->output[o]; - - if (output->crtc != crtc) - continue; - - drmmode_output_dpms(output, drmmode_crtc->pending_dpms_mode); - } - - drmmode_crtc_dpms(crtc, drmmode_crtc->pending_dpms_mode); - } -} - static void drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data) { + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); drmmode_flipdata_ptr flipdata = event_data; if (--flipdata->flip_count == 0) { @@ -2446,7 +2406,8 @@ drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data) free(flipdata); } - drmmode_clear_pending_flip(crtc); + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, + NULL); } static void @@ -2478,7 +2439,8 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, drmmode_crtc->flip_pending); - drmmode_clear_pending_flip(crtc); + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, + NULL); } diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 71d1c4a4..52b76f05 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -92,8 +92,6 @@ typedef struct { PixmapPtr prime_scanout_pixmap; int dpms_mode; - /* For when a flip is pending when DPMS off requested */ - int pending_dpms_mode; CARD64 dpms_last_ust; uint32_t dpms_last_seq; int dpms_last_fps; @@ -145,7 +143,7 @@ drmmode_crtc_can_flip(xf86CrtcPtr crtc) drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; return crtc->enabled && - drmmode_crtc->pending_dpms_mode == DPMSModeOn && + drmmode_crtc->dpms_mode == DPMSModeOn && !drmmode_crtc->rotate.bo && !drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo; } @@ -215,7 +213,6 @@ extern int drmmode_get_crtc_id(xf86CrtcPtr crtc); extern int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling); extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); -extern void drmmode_clear_pending_flip(xf86CrtcPtr crtc); Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, PixmapPtr new_front, uint64_t id, void *data, diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 423d36cb..977504d9 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -732,7 +732,7 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) drmmode_crtc = xf86_crtc->driver_private; if (drmmode_crtc->scanout_update_pending || !drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap || - drmmode_crtc->pending_dpms_mode != DPMSModeOn) + drmmode_crtc->dpms_mode != DPMSModeOn) return; drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, @@ -761,10 +761,12 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) static void radeon_prime_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data) { + RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = event_data; drmmode_crtc->scanout_update_pending = FALSE; - drmmode_clear_pending_flip(crtc); + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, + NULL); } static void @@ -796,7 +798,7 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) drmmode_crtc = crtc->driver_private; if (drmmode_crtc->scanout_update_pending || !drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap || - drmmode_crtc->pending_dpms_mode != DPMSModeOn) + drmmode_crtc->dpms_mode != DPMSModeOn) return; scanout_id = drmmode_crtc->scanout_id ^ 1; @@ -1022,7 +1024,7 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) if (!xf86_crtc->enabled || drmmode_crtc->scanout_update_pending || - drmmode_crtc->pending_dpms_mode != DPMSModeOn) + drmmode_crtc->dpms_mode != DPMSModeOn) return; pDamage = drmmode_crtc->scanout_damage; @@ -1088,7 +1090,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, unsigned scanout_id; if (drmmode_crtc->scanout_update_pending || - drmmode_crtc->pending_dpms_mode != DPMSModeOn) + drmmode_crtc->dpms_mode != DPMSModeOn) return; scanout_id = drmmode_crtc->scanout_id ^ 1; diff --git a/src/radeon_present.c b/src/radeon_present.c index 135a0a97..c7dde0ec 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -379,7 +379,7 @@ modeset: if (!crtc->enabled) continue; - if (drmmode_crtc->pending_dpms_mode == DPMSModeOn) + if (drmmode_crtc->dpms_mode == DPMSModeOn) crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); else diff --git a/src/radeon_video.c b/src/radeon_video.c index d058986a..e08d8e00 100644 --- a/src/radeon_video.c +++ b/src/radeon_video.c @@ -71,7 +71,7 @@ radeon_box_area(BoxPtr box) Bool radeon_crtc_is_enabled(xf86CrtcPtr crtc) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - return drmmode_crtc->pending_dpms_mode == DPMSModeOn; + return drmmode_crtc->dpms_mode == DPMSModeOn; } xf86CrtcPtr -- cgit v1.2.3 From 7c10ee9c88378d773c0bcf651fdc5d9f2c6dc5e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 3 Aug 2017 18:16:36 +0900 Subject: Handle multiple "pending" Present flips The xserver Present code can submit a flip in response to notifying it that a vblank event arrived. This can happen before the completion event of the previous flip is processed. In that case, we were clearing the drmmode_crtc->flip_pending field prematurely. Prevent this by only clearing drmmode_crtc->flip_pending when it matches the framebuffer being scanned out since the flip whose completion event we're processing. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 27 ++++++++++++++++----------- src/drmmode_display.h | 3 ++- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 2692f697..d86c4ba9 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2403,6 +2403,7 @@ drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data) if (!flipdata->fe_crtc) flipdata->fe_crtc = crtc; flipdata->abort(flipdata->fe_crtc, flipdata->event_data); + drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb, NULL); free(flipdata); } @@ -2424,6 +2425,13 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even flipdata->fe_usec = usec; } + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, + flipdata->fb); + if (drmmode_crtc->flip_pending == flipdata->fb) { + drmmode_fb_reference(pRADEONEnt->fd, + &drmmode_crtc->flip_pending, NULL); + } + if (--flipdata->flip_count == 0) { /* Deliver MSC & UST from reference/current CRTC to flip event * handler @@ -2434,13 +2442,9 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even else flipdata->handler(crtc, frame, usec, flipdata->event_data); + drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb, NULL); free(flipdata); } - - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, - drmmode_crtc->flip_pending); - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, - NULL); } @@ -2961,7 +2965,6 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0; drmmode_flipdata_ptr flipdata; uintptr_t drm_queue_seq = 0; - struct drmmode_fb *fb; flipdata = calloc(1, sizeof(drmmode_flipdata_rec)); if (!flipdata) { @@ -2970,8 +2973,9 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, goto error; } - fb = radeon_pixmap_get_fb(new_front); - if (!fb) { + drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb, + radeon_pixmap_get_fb(new_front)); + if (!flipdata->fb) { ErrorF("Failed to get FB for flip\n"); goto error; } @@ -3013,7 +3017,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, if (crtc == ref_crtc) { if (drmmode_page_flip_target_absolute(pRADEONEnt, drmmode_crtc, - fb->handle, + flipdata->fb->handle, flip_flags, drm_queue_seq, target_msc) != 0) @@ -3021,14 +3025,14 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, } else { if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, - fb->handle, + flipdata->fb->handle, flip_flags, drm_queue_seq, 0) != 0) goto flip_error; } drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, - fb); + flipdata->fb); drm_queue_seq = 0; } @@ -3046,6 +3050,7 @@ error: drmmode_flip_abort(crtc, flipdata); else { abort(NULL, data); + drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb, NULL); free(flipdata); } diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 52b76f05..13f301f7 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -56,8 +56,9 @@ typedef struct { } drmmode_rec, *drmmode_ptr; typedef struct { - int flip_count; + struct drmmode_fb *fb; void *event_data; + int flip_count; unsigned int fe_frame; uint64_t fe_usec; xf86CrtcPtr fe_crtc; -- cgit v1.2.3 From 1443270e52e8562bd8dc3603f301963bd4027cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 7 Feb 2017 18:58:23 +0900 Subject: Add source drawable parameter to radeon_scanout_do_update Preparation for following changes, no functional change intended yet. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 3 ++- src/radeon.h | 3 ++- src/radeon_kms.c | 18 +++++++++--------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index d86c4ba9..35b706e0 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -833,7 +833,8 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, *fb = radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); *x = *y = 0; - radeon_scanout_do_update(crtc, scanout_id); + radeon_scanout_do_update(crtc, scanout_id, + &screen->GetWindowPixmap(screen->root)->drawable); radeon_bo_wait(drmmode_crtc->scanout[scanout_id].bo); } } diff --git a/src/radeon.h b/src/radeon.h index b93e2816..864fe7c3 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -664,7 +664,8 @@ extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, Bool radeon_dri3_screen_init(ScreenPtr screen); /* radeon_kms.c */ -Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id); +Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, + DrawablePtr src_draw); void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0) , RegionPtr pBSRegion diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 977504d9..5f02a487 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -890,7 +890,8 @@ radeon_dirty_update(ScrnInfoPtr scrn) #endif Bool -radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id) +radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, + DrawablePtr src_draw) { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; RegionPtr pRegion = DamageRegion(drmmode_crtc->scanout_damage); @@ -930,10 +931,7 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id) PicturePtr src, dst; XID include_inferiors = IncludeInferiors; - src = CreatePicture(None, - &pScreen->root->drawable, - format, - CPSubwindowMode, + src = CreatePicture(None, src_draw, format, CPSubwindowMode, &include_inferiors, serverClient, &error); if (!src) { ErrorF("Failed to create source picture for transformed scanout " @@ -978,8 +976,7 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id) GCPtr gc = GetScratchGC(pDraw->depth, pScreen); ValidateGC(pDraw, gc); - (*gc->ops->CopyArea)(&pScreen->GetWindowPixmap(pScreen->root)->drawable, - pDraw, gc, + (*gc->ops->CopyArea)(src_draw, pDraw, gc, xf86_crtc->x + extents.x1, xf86_crtc->y + extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, extents.x1, extents.y1); @@ -1006,8 +1003,10 @@ radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) { drmmode_crtc_private_ptr drmmode_crtc = event_data; + ScreenPtr screen = crtc->scrn->pScreen; - radeon_scanout_do_update(crtc, drmmode_crtc->scanout_id); + radeon_scanout_do_update(crtc, drmmode_crtc->scanout_id, + &screen->GetWindowPixmap(screen->root)->drawable); radeon_scanout_update_abort(crtc, event_data); } @@ -1094,7 +1093,8 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, return; scanout_id = drmmode_crtc->scanout_id ^ 1; - if (!radeon_scanout_do_update(xf86_crtc, scanout_id)) + if (!radeon_scanout_do_update(xf86_crtc, scanout_id, + &pScreen->GetWindowPixmap(pScreen->root)->drawable)) return; drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, -- cgit v1.2.3 From 65e0c5ea1b4adff21d673dbf54af99704c429627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 8 Feb 2017 17:52:28 +0900 Subject: Pass extents to radeon_scanout_do_update Preparation for following change, no functional change intended yet. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 3 ++- src/radeon.h | 2 +- src/radeon_kms.c | 41 +++++++++++++++++++++-------------------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 35b706e0..1ce58d1e 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -834,7 +834,8 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, *x = *y = 0; radeon_scanout_do_update(crtc, scanout_id, - &screen->GetWindowPixmap(screen->root)->drawable); + &screen->GetWindowPixmap(screen->root)->drawable, + box); radeon_bo_wait(drmmode_crtc->scanout[scanout_id].bo); } } diff --git a/src/radeon.h b/src/radeon.h index 864fe7c3..bba34434 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -665,7 +665,7 @@ Bool radeon_dri3_screen_init(ScreenPtr screen); /* radeon_kms.c */ Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, - DrawablePtr src_draw); + DrawablePtr src_draw, BoxPtr extents); void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0) , RegionPtr pBSRegion diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 5f02a487..17902334 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -891,34 +891,29 @@ radeon_dirty_update(ScrnInfoPtr scrn) Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, - DrawablePtr src_draw) + DrawablePtr src_draw, BoxPtr extents) { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; - RegionPtr pRegion = DamageRegion(drmmode_crtc->scanout_damage); + RegionRec region = { .extents = *extents, .data = NULL }; ScrnInfoPtr scrn = xf86_crtc->scrn; ScreenPtr pScreen = scrn->pScreen; RADEONInfoPtr info = RADEONPTR(scrn); DrawablePtr pDraw; - BoxRec extents; Bool force; if (!xf86_crtc->enabled || - !drmmode_crtc->scanout[scanout_id].pixmap) - return FALSE; - - if (!RegionNotEmpty(pRegion)) + !drmmode_crtc->scanout[scanout_id].pixmap || + extents->x1 >= extents->x2 || extents->y1 >= extents->y2) return FALSE; pDraw = &drmmode_crtc->scanout[scanout_id].pixmap->drawable; - extents = *RegionExtents(pRegion); - if (!radeon_scanout_extents_intersect(xf86_crtc, &extents)) + if (!radeon_scanout_extents_intersect(xf86_crtc, extents)) return FALSE; if (drmmode_crtc->tear_free) { - radeon_sync_scanout_pixmaps(xf86_crtc, pRegion, scanout_id); - RegionCopy(&drmmode_crtc->scanout_last_region, pRegion); + radeon_sync_scanout_pixmaps(xf86_crtc, ®ion, scanout_id); + RegionCopy(&drmmode_crtc->scanout_last_region, ®ion); } - RegionEmpty(pRegion); force = info->accel_state->force; info->accel_state->force = TRUE; @@ -960,9 +955,9 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, pScreen->SourceValidate = NULL; CompositePicture(PictOpSrc, src, NULL, dst, - extents.x1, extents.y1, 0, 0, extents.x1, - extents.y1, extents.x2 - extents.x1, - extents.y2 - extents.y1); + extents->x1, extents->y1, 0, 0, extents->x1, + extents->y1, extents->x2 - extents->x1, + extents->y2 - extents->y1); pScreen->SourceValidate = SourceValidate; free_dst: @@ -977,9 +972,9 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, ValidateGC(pDraw, gc); (*gc->ops->CopyArea)(src_draw, pDraw, gc, - xf86_crtc->x + extents.x1, xf86_crtc->y + extents.y1, - extents.x2 - extents.x1, extents.y2 - extents.y1, - extents.x1, extents.y1); + xf86_crtc->x + extents->x1, xf86_crtc->y + extents->y1, + extents->x2 - extents->x1, extents->y2 - extents->y1, + extents->x1, extents->y1); FreeScratchGC(gc); } @@ -1004,9 +999,12 @@ radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, { drmmode_crtc_private_ptr drmmode_crtc = event_data; ScreenPtr screen = crtc->scrn->pScreen; + RegionPtr region = DamageRegion(drmmode_crtc->scanout_damage); radeon_scanout_do_update(crtc, drmmode_crtc->scanout_id, - &screen->GetWindowPixmap(screen->root)->drawable); + &screen->GetWindowPixmap(screen->root)->drawable, + ®ion->extents); + RegionEmpty(region); radeon_scanout_update_abort(crtc, event_data); } @@ -1083,6 +1081,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, xf86CrtcPtr xf86_crtc) { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; + RegionPtr region = DamageRegion(drmmode_crtc->scanout_damage); ScrnInfoPtr scrn = xf86_crtc->scrn; RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); uintptr_t drm_queue_seq; @@ -1094,8 +1093,10 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, scanout_id = drmmode_crtc->scanout_id ^ 1; if (!radeon_scanout_do_update(xf86_crtc, scanout_id, - &pScreen->GetWindowPixmap(pScreen->root)->drawable)) + &pScreen->GetWindowPixmap(pScreen->root)->drawable, + ®ion->extents)) return; + RegionEmpty(region); drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, RADEON_DRM_QUEUE_CLIENT_DEFAULT, -- cgit v1.2.3 From 4445765af5b97d0cfd10889fe6d6f58f2ce85659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 9 Feb 2017 13:01:03 +0900 Subject: Always allow Present page flipping with TearFree Even if TearFree is active for the the CRTC we're synchronizing to. In that case, for Present flips synchronized to vertical blank, the other scanout buffer is immediately synchronized and flipped to during the target vertical blank period. For Present flips not synchronized to vertical blank, we simply use the MSC and timestamp values of the last vertical blank period for timing purposes, and let the normal TearFree mechanism handle display updates. v2: * Move manpage hunk to next change, since TearFree can still prevent DRI2 page flipping with this change. Reviewed-by: Alex Deucher # v1 --- src/drmmode_display.c | 61 ++++++++++++++++++++++++++++++++++++----- src/drmmode_display.h | 12 ++++++++- src/radeon_kms.c | 27 ++++++++++++++++--- src/radeon_present.c | 75 +++++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 152 insertions(+), 23 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 1ce58d1e..90588671 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -612,6 +612,14 @@ error: static void radeon_screen_damage_report(DamagePtr damage, RegionPtr region, void *closure) { + drmmode_crtc_private_ptr drmmode_crtc = closure; + + if (drmmode_crtc->ignore_damage) { + RegionEmpty(&damage->damage); + drmmode_crtc->ignore_damage = FALSE; + return; + } + /* Only keep track of the extents */ RegionUninit(&damage->damage); damage->damage.data = NULL; @@ -2429,7 +2437,8 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, flipdata->fb); - if (drmmode_crtc->flip_pending == flipdata->fb) { + if (drmmode_crtc->tear_free || + drmmode_crtc->flip_pending == flipdata->fb) { drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, NULL); } @@ -2998,13 +3007,16 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, flipdata->fe_crtc = ref_crtc; for (i = 0; i < config->num_crtc; i++) { + struct drmmode_fb *fb = flipdata->fb; + crtc = config->crtc[i]; + drmmode_crtc = crtc->driver_private; - if (!drmmode_crtc_can_flip(crtc)) + if (!drmmode_crtc_can_flip(crtc) || + (drmmode_crtc->tear_free && crtc != ref_crtc)) continue; flipdata->flip_count++; - drmmode_crtc = crtc->driver_private; drm_queue_seq = radeon_drm_queue_alloc(crtc, client, id, flipdata, @@ -3016,10 +3028,39 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, goto error; } + if (drmmode_crtc->tear_free) { + BoxRec extents = { .x1 = 0, .y1 = 0, + .x2 = new_front->drawable.width, + .y2 = new_front->drawable.height }; + int scanout_id = drmmode_crtc->scanout_id ^ 1; + + if (flip_sync == FLIP_ASYNC) { + if (!drmmode_wait_vblank(crtc, + DRM_VBLANK_RELATIVE | + DRM_VBLANK_EVENT, + 0, drm_queue_seq, + NULL, NULL)) + goto flip_error; + goto next; + } + + fb = radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); + if (!fb) { + ErrorF("Failed to get FB for TearFree flip\n"); + goto error; + } + + radeon_scanout_do_update(crtc, scanout_id, + &new_front->drawable, &extents); + + drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, + drmmode_crtc->scanout_update_pending); + } + if (crtc == ref_crtc) { if (drmmode_page_flip_target_absolute(pRADEONEnt, drmmode_crtc, - flipdata->fb->handle, + fb->handle, flip_flags, drm_queue_seq, target_msc) != 0) @@ -3027,14 +3068,20 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, } else { if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, - flipdata->fb->handle, + fb->handle, flip_flags, drm_queue_seq, 0) != 0) goto flip_error; } - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, - flipdata->fb); + if (drmmode_crtc->tear_free) { + drmmode_crtc->scanout_id ^= 1; + drmmode_crtc->ignore_damage = TRUE; + } + + next: + drmmode_fb_reference(pRADEONEnt->fd, + &drmmode_crtc->flip_pending, fb); drm_queue_seq = 0; } diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 13f301f7..a6db87f8 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -85,6 +85,7 @@ typedef struct { struct drmmode_scanout rotate; struct drmmode_scanout scanout[2]; DamagePtr scanout_damage; + Bool ignore_damage; RegionRec scanout_last_region; unsigned scanout_id; Bool scanout_update_pending; @@ -106,6 +107,14 @@ typedef struct { struct drmmode_fb *flip_pending; /* The FB currently being scanned out by this CRTC, if any */ struct drmmode_fb *fb; + +#ifdef HAVE_PRESENT_H + /* Deferred processing of Present vblank event */ + uint64_t present_vblank_event_id; + uint64_t present_vblank_usec; + unsigned present_vblank_msc; + Bool present_flip_expected; +#endif } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; typedef struct { @@ -146,7 +155,8 @@ drmmode_crtc_can_flip(xf86CrtcPtr crtc) return crtc->enabled && drmmode_crtc->dpms_mode == DPMSModeOn && !drmmode_crtc->rotate.bo && - !drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo; + (drmmode_crtc->tear_free || + !drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo); } diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 17902334..7febf148 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -44,6 +44,10 @@ #include "atipciids.h" +#if HAVE_PRESENT_H +#include +#endif + /* DPMS */ #ifdef HAVE_XEXTPROTO_71 #include @@ -779,6 +783,15 @@ radeon_prime_scanout_flip_handler(xf86CrtcPtr crtc, uint32_t msc, uint64_t usec, drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, drmmode_crtc->flip_pending); radeon_prime_scanout_flip_abort(crtc, event_data); + +#ifdef HAVE_PRESENT_H + if (drmmode_crtc->present_vblank_event_id) { + present_event_notify(drmmode_crtc->present_vblank_event_id, + drmmode_crtc->present_vblank_usec, + drmmode_crtc->present_vblank_msc); + drmmode_crtc->present_vblank_event_id = 0; + } +#endif } static void @@ -1001,10 +1014,14 @@ radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, ScreenPtr screen = crtc->scrn->pScreen; RegionPtr region = DamageRegion(drmmode_crtc->scanout_damage); - radeon_scanout_do_update(crtc, drmmode_crtc->scanout_id, - &screen->GetWindowPixmap(screen->root)->drawable, - ®ion->extents); - RegionEmpty(region); + if (crtc->enabled && + !drmmode_crtc->flip_pending && + drmmode_crtc->dpms_mode == DPMSModeOn) { + if (radeon_scanout_do_update(crtc, drmmode_crtc->scanout_id, + &screen->GetWindowPixmap(screen->root)->drawable, + ®ion->extents)) + RegionEmpty(region); + } radeon_scanout_update_abort(crtc, event_data); } @@ -1021,6 +1038,7 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) if (!xf86_crtc->enabled || drmmode_crtc->scanout_update_pending || + drmmode_crtc->flip_pending || drmmode_crtc->dpms_mode != DPMSModeOn) return; @@ -1088,6 +1106,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, unsigned scanout_id; if (drmmode_crtc->scanout_update_pending || + drmmode_crtc->flip_pending || drmmode_crtc->dpms_mode != DPMSModeOn) return; diff --git a/src/radeon_present.c b/src/radeon_present.c index c7dde0ec..176853d9 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -52,6 +52,7 @@ static present_screen_info_rec radeon_present_screen_info; struct radeon_present_vblank_event { uint64_t event_id; + Bool vblank_for_flip; Bool unflip; }; @@ -119,9 +120,26 @@ static void radeon_present_vblank_handler(xf86CrtcPtr crtc, unsigned int msc, uint64_t usec, void *data) { + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; struct radeon_present_vblank_event *event = data; - present_event_notify(event->event_id, usec, msc); + if (event->vblank_for_flip && + drmmode_crtc->tear_free && + drmmode_crtc->scanout_update_pending) { + if (drmmode_crtc->present_vblank_event_id != 0) { + xf86DrvMsg(crtc->scrn->scrnIndex, X_WARNING, + "Need to handle previously deferred vblank event\n"); + present_event_notify(drmmode_crtc->present_vblank_event_id, + drmmode_crtc->present_vblank_usec, + drmmode_crtc->present_vblank_msc); + } + + drmmode_crtc->present_vblank_event_id = event->event_id; + drmmode_crtc->present_vblank_msc = msc; + drmmode_crtc->present_vblank_usec = usec; + } else + present_event_notify(event->event_id, usec, msc); + free(event); } @@ -144,6 +162,7 @@ static int radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) { xf86CrtcPtr xf86_crtc = crtc->devPrivate; + drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; ScreenPtr screen = crtc->pScreen; struct radeon_present_vblank_event *event; uintptr_t drm_queue_seq; @@ -152,6 +171,9 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) if (!event) return BadAlloc; event->event_id = event_id; + event->vblank_for_flip = drmmode_crtc->present_flip_expected; + drmmode_crtc->present_flip_expected = FALSE; + drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, RADEON_DRM_QUEUE_CLIENT_DEFAULT, event_id, event, @@ -226,8 +248,17 @@ radeon_present_check_unflip(ScrnInfoPtr scrn) return FALSE; for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) { - if (drmmode_crtc_can_flip(config->crtc[i])) - num_crtcs_on++; + xf86CrtcPtr crtc = config->crtc[i]; + + if (drmmode_crtc_can_flip(crtc)) { + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + if (drmmode_crtc->flip_pending) + return FALSE; + + if (!drmmode_crtc->tear_free) + num_crtcs_on++; + } } return num_crtcs_on > 0; @@ -240,10 +271,20 @@ static Bool radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, Bool sync_flip) { + xf86CrtcPtr xf86_crtc = crtc->devPrivate; + drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; ScreenPtr screen = window->drawable.pScreen; - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + ScrnInfoPtr scrn = xf86_crtc->scrn; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); RADEONInfoPtr info = RADEONPTR(scrn); PixmapPtr screen_pixmap; + int num_crtcs_on; + int i; + + drmmode_crtc->present_flip_expected = FALSE; + + if (!scrn->vtSema) + return FALSE; if (!info->allowPageFlip) return FALSE; @@ -262,10 +303,18 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, radeon_present_get_pixmap_tiling_flags(info, screen_pixmap)) return FALSE; - if (!drmmode_crtc_can_flip(crtc->devPrivate)) + for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) { + if (drmmode_crtc_can_flip(config->crtc[i])) + num_crtcs_on++; + else if (config->crtc[i] == crtc->devPrivate) + return FALSE; + } + + if (num_crtcs_on == 0) return FALSE; - return radeon_present_check_unflip(scrn); + drmmode_crtc->present_flip_expected = TRUE; + return TRUE; } /* @@ -304,18 +353,20 @@ static Bool radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, PixmapPtr pixmap, Bool sync_flip) { + xf86CrtcPtr xf86_crtc = crtc->devPrivate; + drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; ScreenPtr screen = crtc->pScreen; - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + ScrnInfoPtr scrn = xf86_crtc->scrn; RADEONInfoPtr info = RADEONPTR(scrn); struct radeon_present_vblank_event *event; - Bool ret; + Bool ret = FALSE; if (!radeon_present_check_flip(crtc, screen->root, pixmap, sync_flip)) - return FALSE; + goto out; event = calloc(1, sizeof(struct radeon_present_vblank_event)); if (!event) - return FALSE; + goto out; event->event_id = event_id; @@ -332,6 +383,8 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, else info->drmmode.present_flipping = TRUE; + out: + drmmode_crtc->present_flip_expected = FALSE; return ret; } @@ -376,7 +429,7 @@ modeset: xf86CrtcPtr crtc = config->crtc[i]; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - if (!crtc->enabled) + if (!crtc->enabled || drmmode_crtc->tear_free) continue; if (drmmode_crtc->dpms_mode == DPMSModeOn) -- cgit v1.2.3 From d314cbfb228bb4b8762714f98d0c114a8ee3f061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 31 Jul 2017 17:12:59 +0900 Subject: Always allow DRI2 page flipping with TearFree Even if TearFree is enabled for the CRTC we're synchronizing to. v2: * Move manpage hunk here from previous change. Reviewed-by: Alex Deucher # v1 --- man/radeon.man | 6 ++---- src/radeon_dri2.c | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/man/radeon.man b/man/radeon.man index 1e9a7beb..9fd863f3 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -285,10 +285,8 @@ Set the default value of the per-output 'TearFree' property, which controls tearing prevention using the hardware page flipping mechanism. TearFree is on for any CRTC associated with one or more outputs with TearFree on. Two separate scanout buffers need to be allocated for each CRTC with TearFree -on. While TearFree is on for any CRTC, it may prevent clients from using -DRI page flipping. If this option is set, the default value of the property -is 'on' or 'off' accordingly. If this option isn't set, the default value of the -property is +on. If this option is set, the default value of the property is 'on' or 'off' +accordingly. If this option isn't set, the default value of the property is .B auto, which means that TearFree is on for outputs with rotation or other RandR transforms, and for RandR 1.4 slave outputs, otherwise off. diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index a0deb6ba..73adbe91 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -760,8 +760,6 @@ can_flip(xf86CrtcPtr crtc, DrawablePtr draw, for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) { if (drmmode_crtc_can_flip(config->crtc[i])) num_crtcs_on++; - else if (config->crtc[i] == crtc) - return FALSE; } return num_crtcs_on > 0 && can_exchange(pScrn, draw, front, back); -- cgit v1.2.3 From 36ce7920136c0d723c9397a84e7dd5926a9c7943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 9 Aug 2017 19:01:15 +0900 Subject: Consolidate radeon_scanout_flip_abort/handler helpers While at it, make them use crtc->driver_private. Reviewed-by: Alex Deucher --- src/radeon_kms.c | 85 ++++++++++++++++++++++++-------------------------------- 1 file changed, 36 insertions(+), 49 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 7febf148..4c001a31 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -518,6 +518,38 @@ radeon_sync_scanout_pixmaps(xf86CrtcPtr xf86_crtc, RegionPtr new_region, RegionUninit(&remaining); } +static void +radeon_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data) +{ + RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + drmmode_crtc->scanout_update_pending = FALSE; + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, + NULL); +} + +static void +radeon_scanout_flip_handler(xf86CrtcPtr crtc, uint32_t msc, uint64_t usec, + void *event_data) +{ + RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, + drmmode_crtc->flip_pending); + radeon_scanout_flip_abort(crtc, event_data); + +#ifdef HAVE_PRESENT_H + if (drmmode_crtc->present_vblank_event_id) { + present_event_notify(drmmode_crtc->present_vblank_event_id, + drmmode_crtc->present_vblank_usec, + drmmode_crtc->present_vblank_msc); + drmmode_crtc->present_vblank_event_id = 0; + } +#endif +} + #ifdef RADEON_PIXMAP_SHARING static RegionPtr @@ -762,38 +794,6 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) drmmode_crtc->scanout_update_pending = TRUE; } -static void -radeon_prime_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data) -{ - RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); - drmmode_crtc_private_ptr drmmode_crtc = event_data; - - drmmode_crtc->scanout_update_pending = FALSE; - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, - NULL); -} - -static void -radeon_prime_scanout_flip_handler(xf86CrtcPtr crtc, uint32_t msc, uint64_t usec, - void *event_data) -{ - RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); - drmmode_crtc_private_ptr drmmode_crtc = event_data; - - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, - drmmode_crtc->flip_pending); - radeon_prime_scanout_flip_abort(crtc, event_data); - -#ifdef HAVE_PRESENT_H - if (drmmode_crtc->present_vblank_event_id) { - present_event_notify(drmmode_crtc->present_vblank_event_id, - drmmode_crtc->present_vblank_usec, - drmmode_crtc->present_vblank_msc); - drmmode_crtc->present_vblank_event_id = 0; - } -#endif -} - static void radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) { @@ -821,9 +821,9 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) drm_queue_seq = radeon_drm_queue_alloc(crtc, RADEON_DRM_QUEUE_CLIENT_DEFAULT, RADEON_DRM_QUEUE_ID_DEFAULT, - drmmode_crtc, - radeon_prime_scanout_flip_handler, - radeon_prime_scanout_flip_abort); + NULL, + radeon_scanout_flip_handler, + radeon_scanout_flip_abort); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM event queue entry failed for PRIME flip.\n"); @@ -1081,19 +1081,6 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) drmmode_crtc->scanout_update_pending = TRUE; } -static void -radeon_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data) -{ - radeon_prime_scanout_flip_abort(crtc, event_data); -} - -static void -radeon_scanout_flip_handler(xf86CrtcPtr crtc, uint32_t msc, uint64_t usec, - void *event_data) -{ - radeon_prime_scanout_flip_handler(crtc, msc, usec, event_data); -} - static void radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, xf86CrtcPtr xf86_crtc) @@ -1120,7 +1107,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, RADEON_DRM_QUEUE_CLIENT_DEFAULT, RADEON_DRM_QUEUE_ID_DEFAULT, - drmmode_crtc, + NULL, radeon_scanout_flip_handler, radeon_scanout_flip_abort); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { -- cgit v1.2.3 From 3e24770b1b472fc15df56d06f5f04778c9db63dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 9 Aug 2017 13:02:34 +0900 Subject: Use xorg_list_append for the DRM event list We were adding entries at the start of the list, i.e. the list was ordered from most recently added to least recently added. However, the corresponding DRM events are generally expected to arrive in the same order as they are queued, which means that radeon_drm_queue_alloc would generally have to traverse the whole list to find the entry corresponding to an arrived event. Fix this by adding entries at the end of the list. Reviewed-by: Alex Deucher --- src/radeon_drm_queue.c | 2 +- src/radeon_list.h | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index 31f24350..37fdafeb 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -105,7 +105,7 @@ radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, e->handler = handler; e->abort = abort; - xorg_list_add(&e->list, &radeon_drm_queue); + xorg_list_append(&e->list, &radeon_drm_queue); return e->seq; } diff --git a/src/radeon_list.h b/src/radeon_list.h index a0038c96..f9e4ff73 100644 --- a/src/radeon_list.h +++ b/src/radeon_list.h @@ -35,6 +35,13 @@ #define xorg_list_del list_del #define xorg_list_for_each_entry list_for_each_entry #define xorg_list_for_each_entry_safe list_for_each_entry_safe + +static inline void +xorg_list_append(struct list *entry, struct list *head) +{ + __list_add(entry, head->prev, head); +} + #endif #endif /* _RADEON_LIST_H_ */ -- cgit v1.2.3 From d822a0f47070374ad0c1a97b559bae27724dc52a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 17 Aug 2017 16:20:52 +0900 Subject: Make radeon_scanout_do_update take a PixmapPtr instead of a DrawablePtr All callers were already passing in a pixmap. This allows simplifying the rotated scanout case slightly. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 6 +++--- src/radeon.h | 2 +- src/radeon_kms.c | 13 ++++++------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 90588671..4839b415 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -842,7 +842,7 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, *x = *y = 0; radeon_scanout_do_update(crtc, scanout_id, - &screen->GetWindowPixmap(screen->root)->drawable, + screen->GetWindowPixmap(screen->root), box); radeon_bo_wait(drmmode_crtc->scanout[scanout_id].bo); } @@ -3050,8 +3050,8 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, goto error; } - radeon_scanout_do_update(crtc, scanout_id, - &new_front->drawable, &extents); + radeon_scanout_do_update(crtc, scanout_id, new_front, + &extents); drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, drmmode_crtc->scanout_update_pending); diff --git a/src/radeon.h b/src/radeon.h index bba34434..71123c7c 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -665,7 +665,7 @@ Bool radeon_dri3_screen_init(ScreenPtr screen); /* radeon_kms.c */ Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, - DrawablePtr src_draw, BoxPtr extents); + PixmapPtr src_pix, BoxPtr extents); void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0) , RegionPtr pBSRegion diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 4c001a31..ca2d36d0 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -904,7 +904,7 @@ radeon_dirty_update(ScrnInfoPtr scrn) Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, - DrawablePtr src_draw, BoxPtr extents) + PixmapPtr src_pix, BoxPtr extents) { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; RegionRec region = { .extents = *extents, .data = NULL }; @@ -937,10 +937,9 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, PictFormatPtr format = PictureWindowFormat(pScreen->root); int error; PicturePtr src, dst; - XID include_inferiors = IncludeInferiors; - src = CreatePicture(None, src_draw, format, CPSubwindowMode, - &include_inferiors, serverClient, &error); + src = CreatePicture(None, &src_pix->drawable, format, 0L, NULL, + serverClient, &error); if (!src) { ErrorF("Failed to create source picture for transformed scanout " "update\n"); @@ -984,7 +983,7 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, GCPtr gc = GetScratchGC(pDraw->depth, pScreen); ValidateGC(pDraw, gc); - (*gc->ops->CopyArea)(src_draw, pDraw, gc, + (*gc->ops->CopyArea)(&src_pix->drawable, pDraw, gc, xf86_crtc->x + extents->x1, xf86_crtc->y + extents->y1, extents->x2 - extents->x1, extents->y2 - extents->y1, extents->x1, extents->y1); @@ -1018,7 +1017,7 @@ radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, !drmmode_crtc->flip_pending && drmmode_crtc->dpms_mode == DPMSModeOn) { if (radeon_scanout_do_update(crtc, drmmode_crtc->scanout_id, - &screen->GetWindowPixmap(screen->root)->drawable, + screen->GetWindowPixmap(screen->root), ®ion->extents)) RegionEmpty(region); } @@ -1099,7 +1098,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, scanout_id = drmmode_crtc->scanout_id ^ 1; if (!radeon_scanout_do_update(xf86_crtc, scanout_id, - &pScreen->GetWindowPixmap(pScreen->root)->drawable, + pScreen->GetWindowPixmap(pScreen->root), ®ion->extents)) return; RegionEmpty(region); -- cgit v1.2.3 From 0472a605e0ec8fec1892bbc3a84698b7ef9c5296 Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Mon, 10 Apr 2017 16:48:21 +0300 Subject: modesetting: re-set the crtc's mode when link-status goes BAD Despite all the careful planning of the kernel, a link may become insufficient to handle the currently-set mode. At this point, the kernel should mark this particular configuration as being broken and potentially prune the mode before setting the offending connector's link-status to BAD and send the userspace a hotplug event. This may happen right after a modeset or later on. Upon receiving a hot-plug event, we iterate through the connectors to re-apply the currently-set mode on all the connectors that have a link-status property set to BAD. The kernel may be able to get the link to work by dropping to using a lower link bpp (with the same display bpp). However, the modeset may fail if the kernel has pruned the mode, so to make users aware of this problem a warning is outputed in the logs to warn about having a potentially-black display. This patch does not modify the current behaviour of always propagating the events to the randr clients. This allows desktop environments to re-probe the connectors and select a new resolution based on the new (currated) mode list if a mode disapeared. This behaviour is expected in order to pass the Display Port compliance tests. (Ported from xserver commit bcee1b76aa0db8525b491485e90b8740763d7de6) [ Michel: Bump libdrm dependency to >= 2.4.78 for DRM_MODE_LINK_STATUS_BAD ] Reviewed-by: Alex Deucher --- configure.ac | 2 +- src/drmmode_display.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index c9bc0a95..170f42ef 100644 --- a/configure.ac +++ b/configure.ac @@ -70,7 +70,7 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto) XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) # Checks for libraries. -PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.60]) +PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.78]) PKG_CHECK_MODULES(LIBDRM_RADEON, [libdrm_radeon]) # Obtain compiler/linker options for the driver dependencies diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 4839b415..f926bc01 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2826,6 +2826,49 @@ radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode) Bool changed = FALSE; int num_dvi = 0, num_hdmi = 0; + /* Try to re-set the mode on all the connectors with a BAD link-state: + * This may happen if a link degrades and a new modeset is necessary, using + * different link-training parameters. If the kernel found that the current + * mode is not achievable anymore, it should have pruned the mode before + * sending the hotplug event. Try to re-set the currently-set mode to keep + * the display alive, this will fail if the mode has been pruned. + * In any case, we will send randr events for the Desktop Environment to + * deal with it, if it wants to. + */ + for (i = 0; i < config->num_output; i++) { + xf86OutputPtr output = config->output[i]; + drmmode_output_private_ptr drmmode_output = output->driver_private; + uint32_t con_id = drmmode_output->mode_output->connector_id; + drmModeConnectorPtr koutput; + + /* Get an updated view of the properties for the current connector and + * look for the link-status property + */ + koutput = drmModeGetConnectorCurrent(pRADEONEnt->fd, con_id); + for (j = 0; koutput && j < koutput->count_props; j++) { + drmModePropertyPtr props; + props = drmModeGetProperty(pRADEONEnt->fd, koutput->props[j]); + if (props && props->flags & DRM_MODE_PROP_ENUM && + !strcmp(props->name, "link-status") && + koutput->prop_values[j] == DRM_MODE_LINK_STATUS_BAD) { + xf86CrtcPtr crtc = output->crtc; + if (!crtc) + continue; + + /* the connector got a link failure, re-set the current mode */ + drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, + crtc->x, crtc->y); + + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "hotplug event: connector %u's link-state is BAD, " + "tried resetting the current mode. You may be left " + "with a black screen if this fails...\n", con_id); + } + drmModeFreeProperty(props); + } + drmModeFreeConnector(koutput); + } + mode_res = drmModeGetResources(pRADEONEnt->fd); if (!mode_res) goto out; -- cgit v1.2.3 From 3f6210ca2c8ef60d59efc8139151d3b9838bb875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 22 Jun 2017 18:37:26 +0900 Subject: Create radeon_pixmap_clear helper Preparatory, no functional change intended yet. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 16 +--------------- src/radeon_bo_helper.c | 21 +++++++++++++++++++++ src/radeon_bo_helper.h | 3 +++ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index f926bc01..387d9e09 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2211,9 +2211,6 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) uint32_t tiling_flags = 0, base_align; PixmapPtr ppix = screen->GetScreenPixmap(screen); void *fb_shadow; - xRectangle rect; - Bool force; - GCPtr gc; if (scrn->virtualX == width && scrn->virtualY == height) return TRUE; @@ -2356,18 +2353,7 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) goto fail; } - /* Clear new buffer */ - gc = GetScratchGC(ppix->drawable.depth, scrn->pScreen); - force = info->accel_state->force; - info->accel_state->force = TRUE; - ValidateGC(&ppix->drawable, gc); - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - (*gc->ops->PolyFillRect)(&ppix->drawable, gc, 1, &rect); - FreeScratchGC(gc); - info->accel_state->force = force; + radeon_pixmap_clear(ppix); radeon_cs_flush_indirect(scrn); radeon_bo_wait(info->front_bo); diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c index a8ba7618..01b9e3df 100644 --- a/src/radeon_bo_helper.c +++ b/src/radeon_bo_helper.c @@ -195,6 +195,27 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, return bo; } +/* Clear the pixmap contents to black */ +void +radeon_pixmap_clear(PixmapPtr pixmap) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen)); + GCPtr gc = GetScratchGC(pixmap->drawable.depth, screen); + Bool force = info->accel_state->force; + xRectangle rect; + + info->accel_state->force = TRUE; + ValidateGC(&pixmap->drawable, gc); + rect.x = 0; + rect.y = 0; + rect.width = pixmap->drawable.width; + rect.height = pixmap->drawable.height; + gc->ops->PolyFillRect(&pixmap->drawable, gc, 1, &rect); + FreeScratchGC(gc); + info->accel_state->force = force; +} + /* Get GEM handle for the pixmap */ Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle) { diff --git a/src/radeon_bo_helper.h b/src/radeon_bo_helper.h index 77134250..e1856adb 100644 --- a/src/radeon_bo_helper.h +++ b/src/radeon_bo_helper.h @@ -28,6 +28,9 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, int usage_hint, int bitsPerPixel, int *new_pitch, struct radeon_surface *new_surface, uint32_t *new_tiling); +extern void +radeon_pixmap_clear(PixmapPtr pixmap); + extern uint32_t radeon_get_pixmap_tiling_flags(PixmapPtr pPix); -- cgit v1.2.3 From 4bc992c31059eb50e22df4ebf5b92d08411f41ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 23 Aug 2017 17:24:53 +0900 Subject: Create drmmode_set_mode helper Preparatory, no functional change intended yet. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 82 ++++++++++++++++++++++++++++++--------------------- src/drmmode_display.h | 3 ++ 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 387d9e09..791d5998 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -860,6 +860,52 @@ drmmode_crtc_gamma_do_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, blue); } +Bool +drmmode_set_mode(xf86CrtcPtr crtc, struct drmmode_fb *fb, DisplayModePtr mode, + int x, int y) +{ + ScrnInfoPtr scrn = crtc->scrn; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + uint32_t *output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); + int output_count = 0; + drmModeModeInfo kmode; + Bool ret; + int i; + + if (!output_ids) + return FALSE; + + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + drmmode_output_private_ptr drmmode_output = output->driver_private; + + if (output->crtc != crtc) + continue; + + output_ids[output_count] = drmmode_output->mode_output->connector_id; + output_count++; + } + + drmmode_ConvertToKMode(scrn, &kmode, mode); + + ret = drmModeSetCrtc(pRADEONEnt->fd, + drmmode_crtc->mode_crtc->crtc_id, + fb->handle, x, y, output_ids, + output_count, &kmode) == 0; + + if (ret) { + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, fb); + } else { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "failed to set mode: %s\n", strerror(errno)); + } + + free(output_ids); + return ret; +} + static Bool drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y) @@ -875,12 +921,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, int saved_x, saved_y; Rotation saved_rotation; DisplayModeRec saved_mode; - uint32_t *output_ids = NULL; - int output_count = 0; Bool ret = FALSE; int i; struct drmmode_fb *fb = NULL; - drmModeModeInfo kmode; /* The root window contents may be undefined before the WindowExposures * hook is called for it, so bail if we get here before that @@ -899,22 +942,6 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, crtc->y = y; crtc->rotation = rotation; - output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); - if (!output_ids) - goto done; - - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - drmmode_output_private_ptr drmmode_output; - - if (output->crtc != crtc) - continue; - - drmmode_output = output->driver_private; - output_ids[output_count] = drmmode_output->mode_output->connector_id; - output_count++; - } - if (!drmmode_handle_transform(crtc)) goto done; @@ -925,8 +952,6 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, drmmode_crtc_gamma_do_set(crtc, crtc->gamma_red, crtc->gamma_green, crtc->gamma_blue, crtc->gamma_size); - drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); - #ifdef RADEON_PIXMAP_SHARING if (drmmode_crtc->prime_scanout_pixmap) { drmmode_crtc_prime_scanout_update(crtc, mode, scanout_id, @@ -967,17 +992,10 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, drmmode_crtc->flip_pending); - if (drmModeSetCrtc(pRADEONEnt->fd, - drmmode_crtc->mode_crtc->crtc_id, - fb->handle, x, y, output_ids, - output_count, &kmode) != 0) { - xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, - "failed to set mode: %s\n", strerror(errno)); + if (!drmmode_set_mode(crtc, fb, mode, x, y)) goto done; - } else { - ret = TRUE; - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, fb); - } + + ret = TRUE; if (pScreen) xf86CrtcSetScreenSubpixelOrder(pScreen); @@ -1032,8 +1050,6 @@ done: } } - free(output_ids); - return ret; } diff --git a/src/drmmode_display.h b/src/drmmode_display.h index a6db87f8..00b5e811 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -220,6 +220,9 @@ extern void drmmode_scanout_free(ScrnInfoPtr scrn); extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode); extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode); +Bool drmmode_set_mode(xf86CrtcPtr crtc, struct drmmode_fb *fb, + DisplayModePtr mode, int x, int y); + extern int drmmode_get_crtc_id(xf86CrtcPtr crtc); extern int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling); extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); -- cgit v1.2.3 From 20f6b56fdb74d88086e8e094013fedbb14e50a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 24 Aug 2017 17:10:29 +0900 Subject: Create radeon_pixmap_get_fb_ptr helper Preparatory, no functional change intended yet. Also inline radeon_pixmap_create_fb into radeon_pixmap_get_fb, since there's only one call-site anymore. Reviewed-by: Alex Deucher --- src/radeon.h | 53 +++++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/src/radeon.h b/src/radeon.h index 71123c7c..5ce9999a 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -842,24 +842,10 @@ radeon_fb_create(int drm_fd, uint32_t width, uint32_t height, uint8_t depth, return NULL; } -static inline struct drmmode_fb* -radeon_pixmap_create_fb(int drm_fd, PixmapPtr pix) -{ - uint32_t handle; - - if (!radeon_get_pixmap_handle(pix, &handle)) - return NULL; - - return radeon_fb_create(drm_fd, pix->drawable.width, pix->drawable.height, - pix->drawable.depth, pix->drawable.bitsPerPixel, - pix->devKind, handle); -} - -static inline struct drmmode_fb* -radeon_pixmap_get_fb(PixmapPtr pix) +static inline struct drmmode_fb** +radeon_pixmap_get_fb_ptr(PixmapPtr pix) { ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); RADEONInfoPtr info = RADEONPTR(scrn); #ifdef USE_GLAMOR @@ -869,10 +855,7 @@ radeon_pixmap_get_fb(PixmapPtr pix) if (!priv) return NULL; - if (!priv->fb) - priv->fb = radeon_pixmap_create_fb(pRADEONEnt->fd, pix); - - return priv->fb; + return &priv->fb; } else #endif if (info->accelOn) @@ -883,15 +866,37 @@ radeon_pixmap_get_fb(PixmapPtr pix) if (!driver_priv) return NULL; - if (!driver_priv->fb) - driver_priv->fb = radeon_pixmap_create_fb(pRADEONEnt->fd, pix); - - return driver_priv->fb; + return &driver_priv->fb; } return NULL; } +static inline struct drmmode_fb* +radeon_pixmap_get_fb(PixmapPtr pix) +{ + struct drmmode_fb **fb_ptr = radeon_pixmap_get_fb_ptr(pix); + + if (!fb_ptr) + return NULL; + + if (!*fb_ptr) { + uint32_t handle; + + if (radeon_get_pixmap_handle(pix, &handle)) { + ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + + *fb_ptr = radeon_fb_create(pRADEONEnt->fd, pix->drawable.width, + pix->drawable.height, pix->drawable.depth, + pix->drawable.bitsPerPixel, pix->devKind, + handle); + } + } + + return *fb_ptr; +} + #define CP_PACKET0(reg, n) \ (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) #define CP_PACKET1(reg0, reg1) \ -- cgit v1.2.3 From 7f0cd68d1b0c132e32ae736371bce3e12ed33c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 28 Aug 2017 17:53:19 +0900 Subject: Create radeon_master_screen helper Preparatory, no functional change intended yet. Reviewed-by: Alex Deucher --- src/radeon.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/radeon.h b/src/radeon.h index 5ce9999a..319565a1 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -185,6 +185,15 @@ typedef enum { #define radeon_is_gpu_screen(screen) (screen)->isGPU #define radeon_is_gpu_scrn(scrn) (scrn)->is_gpu +static inline ScreenPtr +radeon_master_screen(ScreenPtr screen) +{ + if (screen->current_master) + return screen->current_master; + + return screen; +} + static inline ScreenPtr radeon_dirty_master(PixmapDirtyUpdatePtr dirty) { @@ -194,10 +203,7 @@ radeon_dirty_master(PixmapDirtyUpdatePtr dirty) ScreenPtr screen = dirty->src->drawable.pScreen; #endif - if (screen->current_master) - return screen->current_master; - - return screen; + return radeon_master_screen(screen); } static inline Bool -- cgit v1.2.3 From 06a465484101f21e99d3a0a62fb03440bcaff93e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 23 Aug 2017 18:00:15 +0900 Subject: Make all active CRTCs scan out an all-black framebuffer in LeaveVT And destroy all other FBs. This is so that other DRM masters can only get access to this all-black FB, not to any other FB we created, while we're switched away and not DRM master. Fixes: 55e513b978b2 ("Use reference counting for tracking KMS framebuffer lifetimes") Reviewed-by: Alex Deucher --- src/drmmode_display.c | 4 +-- src/drmmode_display.h | 4 +++ src/radeon_kms.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 98 insertions(+), 8 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 791d5998..ba170ee6 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -536,7 +536,7 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, } } -static void +void drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc) { drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, @@ -558,7 +558,7 @@ drmmode_scanout_free(ScrnInfoPtr scrn) drmmode_crtc_scanout_free(xf86_config->crtc[c]->driver_private); } -static PixmapPtr +PixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, int width, int height) { diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 00b5e811..ace059dc 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -216,6 +216,10 @@ extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); extern void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, struct drmmode_scanout *scanout); extern void drmmode_scanout_free(ScrnInfoPtr scrn); +void drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc); +PixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc, + struct drmmode_scanout *scanout, + int width, int height); extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode); extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index ca2d36d0..5410c420 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -32,6 +32,7 @@ #include /* Driver data structures */ #include "radeon.h" +#include "radeon_bo_helper.h" #include "radeon_drm_queue.h" #include "radeon_glamor.h" #include "radeon_reg.h" @@ -1158,9 +1159,10 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); pScreen->BlockHandler = RADEONBlockHandler_KMS; - if (!pScrn->vtSema) { - radeon_cs_flush_indirect(pScrn); - + if (!xf86ScreenToScrn(radeon_master_screen(pScreen))->vtSema) { + /* Unreference the all-black FB created by RADEONLeaveVT_KMS. After + * this, there should be no FB left created by this driver. + */ for (c = 0; c < xf86_config->num_crtc; c++) { drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[c]->driver_private; @@ -2472,21 +2474,105 @@ Bool RADEONEnterVT_KMS(VT_FUNC_ARGS_DECL) } +static void +pixmap_unref_fb(void *value, XID id, void *cdata) +{ + PixmapPtr pixmap = value; + RADEONEntPtr pRADEONEnt = cdata; + struct drmmode_fb **fb_ptr = radeon_pixmap_get_fb_ptr(pixmap); + + if (fb_ptr) + drmmode_fb_reference(pRADEONEnt->fd, fb_ptr, NULL); +} + void RADEONLeaveVT_KMS(VT_FUNC_ARGS_DECL) { SCRN_INFO_PTR(arg); RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + ScreenPtr pScreen = pScrn->pScreen; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + struct drmmode_scanout black_scanout = { .pixmap = NULL, .bo = NULL }; + xf86CrtcPtr crtc; + drmmode_crtc_private_ptr drmmode_crtc; + unsigned w = 0, h = 0; + int i; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONLeaveVT_KMS\n"); - radeon_drop_drm_master(pScrn); + /* Compute maximum scanout dimensions of active CRTCs */ + for (i = 0; i < xf86_config->num_crtc; i++) { + crtc = xf86_config->crtc[i]; + drmmode_crtc = crtc->driver_private; + + if (!drmmode_crtc->fb) + continue; + + w = max(w, crtc->mode.HDisplay); + h = max(h, crtc->mode.VDisplay); + } + + /* Make all active CRTCs scan out from an all-black framebuffer */ + if (w > 0 && h > 0) { + if (drmmode_crtc_scanout_create(crtc, &black_scanout, w, h)) { + struct drmmode_fb *black_fb = + radeon_pixmap_get_fb(black_scanout.pixmap); + + radeon_pixmap_clear(black_scanout.pixmap); + radeon_cs_flush_indirect(pScrn); + radeon_bo_wait(black_scanout.bo); + + for (i = 0; i < xf86_config->num_crtc; i++) { + crtc = xf86_config->crtc[i]; + drmmode_crtc = crtc->driver_private; + + if (drmmode_crtc->fb) { + if (black_fb) { + drmmode_set_mode(crtc, black_fb, &crtc->mode, 0, 0); + } else { + drmModeSetCrtc(pRADEONEnt->fd, + drmmode_crtc->mode_crtc->crtc_id, 0, 0, + 0, NULL, 0, NULL); + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, + NULL); + } + + if (pScrn->is_gpu) { + if (drmmode_crtc->scanout[0].pixmap) + pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap, + None, pRADEONEnt); + if (drmmode_crtc->scanout[1].pixmap) + pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap, + None, pRADEONEnt); + } else { + drmmode_crtc_scanout_free(drmmode_crtc); + } + } + } + } + } xf86RotateFreeShadow(pScrn); - if (!pScrn->is_gpu) - drmmode_scanout_free(pScrn); + drmmode_crtc_scanout_destroy(&info->drmmode, &black_scanout); + + /* Unreference FBs of all pixmaps. After this, the only FB remaining + * should be the all-black one being scanned out by active CRTCs + */ + for (i = 0; i < currentMaxClients; i++) { + if (i > 0 && + (!clients[i] || clients[i]->clientState != ClientStateRunning)) + continue; + + FindClientResourcesByType(clients[i], RT_PIXMAP, pixmap_unref_fb, + pRADEONEnt); + } + pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pRADEONEnt); xf86_hide_cursors (pScrn); + + radeon_drop_drm_master(pScrn); + info->accel_state->XInited3D = FALSE; info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; -- cgit v1.2.3 From e4a3df19d588a4310fcb889ef34e205d0e92e4d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 28 Aug 2017 17:54:23 +0900 Subject: Remove drmmode_scanout_free Not used anymore. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 10 ---------- src/drmmode_display.h | 1 - 2 files changed, 11 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index ba170ee6..afb44241 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -548,16 +548,6 @@ drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc) DamageDestroy(drmmode_crtc->scanout_damage); } -void -drmmode_scanout_free(ScrnInfoPtr scrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int c; - - for (c = 0; c < xf86_config->num_crtc; c++) - drmmode_crtc_scanout_free(xf86_config->crtc[c]->driver_private); -} - PixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, int width, int height) diff --git a/src/drmmode_display.h b/src/drmmode_display.h index ace059dc..8387279f 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -215,7 +215,6 @@ extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); extern void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, struct drmmode_scanout *scanout); -extern void drmmode_scanout_free(ScrnInfoPtr scrn); void drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc); PixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, -- cgit v1.2.3 From 9d9c565c84601f4c6c73ad769f86491088683f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 29 Aug 2017 18:07:51 +0900 Subject: Use a timer for unreferencing the all-black FB The timer fires 1 second after LeaveVT. This gives the next DRM master enough time to set up scanout of its own buffers. Fixes prolonged intermittent black screen when switching from Xorg to e.g. the GDM Wayland mode login VT. Fixes: 06a465484101 ("Make all active CRTCs scan out an all-black framebuffer in LeaveVT") Reviewed-by: Alex Deucher --- src/radeon_kms.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 5410c420..01594c6c 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1150,7 +1150,6 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) { SCREEN_PTR(arg); ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int c; @@ -1159,19 +1158,8 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); pScreen->BlockHandler = RADEONBlockHandler_KMS; - if (!xf86ScreenToScrn(radeon_master_screen(pScreen))->vtSema) { - /* Unreference the all-black FB created by RADEONLeaveVT_KMS. After - * this, there should be no FB left created by this driver. - */ - for (c = 0; c < xf86_config->num_crtc; c++) { - drmmode_crtc_private_ptr drmmode_crtc = - xf86_config->crtc[c]->driver_private; - - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL); - } - + if (!xf86ScreenToScrn(radeon_master_screen(pScreen))->vtSema) return; - } if (!radeon_is_gpu_screen(pScreen)) { @@ -2473,6 +2461,30 @@ Bool RADEONEnterVT_KMS(VT_FUNC_ARGS_DECL) return TRUE; } +static +CARD32 cleanup_black_fb(OsTimerPtr timer, CARD32 now, pointer data) +{ + ScreenPtr screen = data; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + if (xf86ScreenToScrn(radeon_master_screen(screen))->vtSema) + return 0; + + /* Unreference the all-black FB created by RADEONLeaveVT_KMS. After + * this, there should be no FB left created by this driver. + */ + for (c = 0; c < xf86_config->num_crtc; c++) { + drmmode_crtc_private_ptr drmmode_crtc = + xf86_config->crtc[c]->driver_private; + + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL); + } + + return 0; +} static void pixmap_unref_fb(void *value, XID id, void *cdata) @@ -2569,6 +2581,8 @@ void RADEONLeaveVT_KMS(VT_FUNC_ARGS_DECL) } pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pRADEONEnt); + TimerSet(NULL, 0, 1000, cleanup_black_fb, pScreen); + xf86_hide_cursors (pScrn); radeon_drop_drm_master(pScrn); -- cgit v1.2.3 From 5cdd334b3402c2431deb3a87a8d04ef590da53ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 30 Aug 2017 18:48:19 +0900 Subject: Require xserver >= 1.13 xserver 1.13.0 was released on September 6th, 2012, almost 5 years ago. This allows cleaning up a bunch of backwards compatibility code. Reviewed-by: Alex Deucher Reviewed-by: Emil Velikov --- configure.ac | 8 +---- src/Makefile.am | 1 - src/compat-api.h | 70 +++---------------------------------------- src/drmmode_display.c | 55 +++++++--------------------------- src/evergreen_exa.c | 2 -- src/r600_exa.c | 2 -- src/radeon.h | 14 +-------- src/radeon_bo_helper.c | 13 ++------ src/radeon_dri2.c | 50 +++++-------------------------- src/radeon_drm_queue.c | 3 +- src/radeon_exa.c | 2 -- src/radeon_exa_funcs.c | 2 -- src/radeon_glamor.c | 6 ---- src/radeon_glamor.h | 4 --- src/radeon_glamor_wrappers.c | 4 +-- src/radeon_kms.c | 71 +++++++++++++------------------------------- src/radeon_list.h | 47 ----------------------------- src/radeon_probe.h | 16 +++++----- 18 files changed, 59 insertions(+), 311 deletions(-) delete mode 100644 src/radeon_list.h diff --git a/configure.ac b/configure.ac index 170f42ef..9c595f8b 100644 --- a/configure.ac +++ b/configure.ac @@ -74,7 +74,7 @@ PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.78]) PKG_CHECK_MODULES(LIBDRM_RADEON, [libdrm_radeon]) # Obtain compiler/linker options for the driver dependencies -PKG_CHECK_MODULES(XORG, [xorg-server >= 1.10 xproto fontsproto xf86driproto $REQUIRED_MODULES]) +PKG_CHECK_MODULES(XORG, [xorg-server >= 1.13 xproto fontsproto xf86driproto $REQUIRED_MODULES]) PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1], HAVE_XEXTPROTO_71="yes"; AC_DEFINE(HAVE_XEXTPROTO_71, 1, [xextproto 7.1 available]), HAVE_XEXTPROTO_71="no") @@ -172,12 +172,6 @@ AC_CHECK_DECL(xf86CursorResetCursor, [#include #include ]) -AC_CHECK_DECL(xorg_list_init, - [AC_DEFINE(HAVE_XORG_LIST, 1, [Have xorg_list API])], [], - [#include - #include "xorg-server.h" - #include "list.h"]) - AC_CHECK_HEADERS([misyncshm.h], [], [], [#include #include diff --git a/src/Makefile.am b/src/Makefile.am index 8f39e213..ed1bfa9e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -96,7 +96,6 @@ EXTRA_DIST = \ radeon_exa_shared.h \ radeon_glamor.h \ radeon.h \ - radeon_list.h \ radeon_probe.h \ radeon_reg.h \ radeon_version.h \ diff --git a/src/compat-api.h b/src/compat-api.h index 80a3ac46..f4e7524f 100644 --- a/src/compat-api.h +++ b/src/compat-api.h @@ -23,77 +23,15 @@ * Author: Dave Airlie */ -/* this file provides API compat between server post 1.13 and pre it, - it should be reused inside as many drivers as possible */ #ifndef COMPAT_API_H #define COMPAT_API_H -#ifndef GLYPH_HAS_GLYPH_PICTURE_ACCESSOR -#define GetGlyphPicture(g, s) GlyphPicture((g))[(s)->myNum] -#define SetGlyphPicture(g, s, p) GlyphPicture((g))[(s)->myNum] = p -#endif - -#ifndef XF86_HAS_SCRN_CONV -#define xf86ScreenToScrn(s) xf86Screens[(s)->myNum] -#define xf86ScrnToScreen(s) screenInfo.screens[(s)->scrnIndex] -#endif - -#ifndef XF86_SCRN_INTERFACE - -#define SCRN_ARG_TYPE int -#define SCRN_INFO_PTR(arg1) ScrnInfoPtr pScrn = xf86Screens[(arg1)] - -#define SCREEN_ARG_TYPE int -#define SCREEN_PTR(arg1) ScreenPtr pScreen = screenInfo.screens[(arg1)] - -#define SCREEN_INIT_ARGS_DECL int i, ScreenPtr pScreen, int argc, char **argv - -#define BLOCKHANDLER_ARGS_DECL int arg, pointer blockData, pointer pTimeout, pointer pReadmask -#define BLOCKHANDLER_ARGS arg, blockData, pTimeout, pReadmask - -#define CLOSE_SCREEN_ARGS_DECL int scrnIndex, ScreenPtr pScreen -#define CLOSE_SCREEN_ARGS scrnIndex, pScreen - -#define ADJUST_FRAME_ARGS_DECL int arg, int x, int y, int flags - -#define SWITCH_MODE_ARGS_DECL int arg, DisplayModePtr mode, int flags - -#define FREE_SCREEN_ARGS_DECL int arg, int flags - -#define VT_FUNC_ARGS_DECL int arg, int flags -#define VT_FUNC_ARGS(flags) pScrn->scrnIndex, (flags) - -#define XF86_ENABLEDISABLEFB_ARG(x) ((x)->scrnIndex) -#else -#define SCRN_ARG_TYPE ScrnInfoPtr -#define SCRN_INFO_PTR(arg1) ScrnInfoPtr pScrn = (arg1) - -#define SCREEN_ARG_TYPE ScreenPtr -#define SCREEN_PTR(arg1) ScreenPtr pScreen = (arg1) - -#define SCREEN_INIT_ARGS_DECL ScreenPtr pScreen, int argc, char **argv - #if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(23, 0) -#define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer pTimeout -#define BLOCKHANDLER_ARGS arg, pTimeout +#define BLOCKHANDLER_ARGS_DECL ScreenPtr pScreen, pointer pTimeout +#define BLOCKHANDLER_ARGS pScreen, pTimeout #else -#define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer pTimeout, pointer pReadmask -#define BLOCKHANDLER_ARGS arg, pTimeout, pReadmask -#endif - -#define CLOSE_SCREEN_ARGS_DECL ScreenPtr pScreen -#define CLOSE_SCREEN_ARGS pScreen - -#define ADJUST_FRAME_ARGS_DECL ScrnInfoPtr arg, int x, int y -#define SWITCH_MODE_ARGS_DECL ScrnInfoPtr arg, DisplayModePtr mode - -#define FREE_SCREEN_ARGS_DECL ScrnInfoPtr arg - -#define VT_FUNC_ARGS_DECL ScrnInfoPtr arg -#define VT_FUNC_ARGS(flags) pScrn - -#define XF86_ENABLEDISABLEFB_ARG(x) (x) - +#define BLOCKHANDLER_ARGS_DECL ScreenPtr pScreen, pointer pTimeout, pointer pReadmask +#define BLOCKHANDLER_ARGS pScreen, pTimeout, pReadmask #endif #endif diff --git a/src/drmmode_display.c b/src/drmmode_display.c index afb44241..369c1efc 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -34,18 +34,16 @@ #include #include "cursorstr.h" #include "damagestr.h" +#include "list.h" #include "micmap.h" #include "xf86cmap.h" #include "xf86Priv.h" #include "radeon.h" #include "radeon_bo_helper.h" #include "radeon_glamor.h" -#include "radeon_list.h" #include "radeon_reg.h" -#ifdef RADEON_PIXMAP_SHARING #include -#endif #include "drmmode_display.h" @@ -637,7 +635,7 @@ drmmode_can_use_hw_cursor(xf86CrtcPtr crtc) if (crtc->transformPresent) return FALSE; -#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7 +#if XF86_CRTC_VERSION < 7 /* Xorg doesn't correctly handle cursor position transform in the * rotation case */ @@ -646,12 +644,10 @@ drmmode_can_use_hw_cursor(xf86CrtcPtr crtc) return FALSE; #endif -#if defined(RADEON_PIXMAP_SHARING) /* HW cursor not supported with RandR 1.4 multihead up to 1.18.99.901 */ if (xorgGetVersion() <= XORG_VERSION_NUMERIC(1,18,99,901,0) && !xorg_list_is_empty(&crtc->scrn->pScreen->pixmap_dirty_list)) return FALSE; -#endif return TRUE; } @@ -675,7 +671,7 @@ drmmode_crtc_update_tear_free(xf86CrtcPtr crtc) if (drmmode_output->tear_free == 1 || (drmmode_output->tear_free == 2 && - (radeon_is_gpu_screen(crtc->scrn->pScreen) || + (crtc->scrn->pScreen->isGPU || info->shadow_primary || crtc->transformPresent || crtc->rotation != RR_Rotate_0))) { drmmode_crtc->tear_free = TRUE; @@ -684,8 +680,6 @@ drmmode_crtc_update_tear_free(xf86CrtcPtr crtc) } } -#if XF86_CRTC_VERSION >= 4 - #if XF86_CRTC_VERSION < 7 #define XF86DriverTransformOutput TRUE #define XF86DriverTransformNone FALSE @@ -714,17 +708,6 @@ drmmode_handle_transform(xf86CrtcPtr crtc) return ret; } -#else - -static Bool -drmmode_handle_transform(xf86CrtcPtr crtc) -{ - return xf86CrtcRotate(crtc); -} - -#endif - -#ifdef RADEON_PIXMAP_SHARING static void drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, @@ -784,7 +767,6 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, drmmode_crtc->scanout_id = scanout_id; } -#endif /* RADEON_PIXMAP_SHARING */ static void drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, @@ -942,21 +924,16 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, drmmode_crtc_gamma_do_set(crtc, crtc->gamma_red, crtc->gamma_green, crtc->gamma_blue, crtc->gamma_size); -#ifdef RADEON_PIXMAP_SHARING if (drmmode_crtc->prime_scanout_pixmap) { drmmode_crtc_prime_scanout_update(crtc, mode, scanout_id, &fb, &x, &y); - } else -#endif - if (drmmode_crtc->rotate.pixmap) { + } else if (drmmode_crtc->rotate.pixmap) { fb = radeon_pixmap_get_fb(drmmode_crtc->rotate.pixmap); x = y = 0; - } else if (!radeon_is_gpu_screen(pScreen) && + } else if (!pScreen->isGPU && (drmmode_crtc->tear_free || -#if XF86_CRTC_VERSION >= 4 crtc->driverIsPerformingTransform || -#endif info->shadow_primary)) { drmmode_crtc_scanout_update(crtc, mode, scanout_id, &fb, &x, &y); @@ -1055,7 +1032,7 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); -#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7 +#if XF86_CRTC_VERSION < 7 if (crtc->driverIsPerformingTransform) { x += crtc->x; y += crtc->y; @@ -1066,7 +1043,7 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) drmModeMoveCursor(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); } -#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7 +#if XF86_CRTC_VERSION < 7 static int drmmode_cursor_src_offset(Rotation rotation, int width, int height, @@ -1137,7 +1114,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) /* cursor should be mapped already */ ptr = (uint32_t *)(drmmode_crtc->cursor_bo->ptr); -#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7 +#if XF86_CRTC_VERSION < 7 if (crtc->driverIsPerformingTransform) { uint32_t cursor_w = info->cursor_w, cursor_h = info->cursor_h; int dstx, dsty; @@ -1313,7 +1290,6 @@ drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, #endif } -#ifdef RADEON_PIXMAP_SHARING static Bool drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) { @@ -1365,7 +1341,6 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) #endif return TRUE; } -#endif static xf86CrtcFuncsRec drmmode_crtc_funcs = { .dpms = drmmode_crtc_dpms, @@ -1384,9 +1359,7 @@ static xf86CrtcFuncsRec drmmode_crtc_funcs = { .shadow_allocate = drmmode_crtc_shadow_allocate, .shadow_destroy = drmmode_crtc_shadow_destroy, .destroy = NULL, /* XXX */ -#ifdef RADEON_PIXMAP_SHARING .set_scanout_pixmap = drmmode_set_scanout_pixmap, -#endif }; int drmmode_get_crtc_id(xf86CrtcPtr crtc) @@ -1873,16 +1846,14 @@ drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name, if (output) { snprintf(name, 32, "%s-%s", output->name, extra_path); } else { - if (koutput->connector_type >= NUM_OUTPUT_NAMES) + if (koutput->connector_type >= NUM_OUTPUT_NAMES) { snprintf(name, 32, "Unknown%d-%d", koutput->connector_type, koutput->connector_type_id - 1); -#ifdef RADEON_PIXMAP_SHARING - else if (pScrn->is_gpu) + } else if (pScrn->is_gpu) { snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type], pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, koutput->connector_type_id - 1); -#endif - else { + } else { /* need to do smart conversion here for compat with non-kms ATI driver */ if (koutput->connector_type_id == 1) { switch(koutput->connector_type) { @@ -2542,9 +2513,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) int i, num_dvi = 0, num_hdmi = 0; drmModeResPtr mode_res; unsigned int crtcs_needed = 0; -#ifdef RADEON_PIXMAP_SHARING char *bus_id_string, *provider_name; -#endif xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); @@ -2585,13 +2554,11 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) /* workout clones */ drmmode_clones_init(pScrn, drmmode, mode_res); -#ifdef RADEON_PIXMAP_SHARING bus_id_string = DRICreatePCIBusID(info->PciInfo); XNFasprintf(&provider_name, "%s @ %s", pScrn->chipset, bus_id_string); free(bus_id_string); xf86ProviderSetup(pScrn, NULL, provider_name); free(provider_name); -#endif xf86InitialConfiguration(pScrn, TRUE); diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c index d788bfc7..90c9b6d9 100644 --- a/src/evergreen_exa.c +++ b/src/evergreen_exa.c @@ -2055,10 +2055,8 @@ EVERGREENDrawInit(ScreenPtr pScreen) info->accel_state->exa->UploadToScreen = EVERGREENUploadToScreen; info->accel_state->exa->DownloadFromScreen = EVERGREENDownloadFromScreen; info->accel_state->exa->CreatePixmap2 = RADEONEXACreatePixmap2; -#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 6) info->accel_state->exa->SharePixmapBacking = RADEONEXASharePixmapBacking; info->accel_state->exa->SetSharedPixmapBacking = RADEONEXASetSharedPixmapBacking; -#endif info->accel_state->exa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_SUPPORTS_PREPARE_AUX | EXA_HANDLES_PIXMAPS | EXA_MIXED_PIXMAPS; info->accel_state->exa->pixmapOffsetAlign = 256; diff --git a/src/r600_exa.c b/src/r600_exa.c index e9ac721d..22d4b316 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -2034,10 +2034,8 @@ R600DrawInit(ScreenPtr pScreen) info->accel_state->exa->UploadToScreen = R600UploadToScreenCS; info->accel_state->exa->DownloadFromScreen = R600DownloadFromScreenCS; info->accel_state->exa->CreatePixmap2 = RADEONEXACreatePixmap2; -#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 6) info->accel_state->exa->SharePixmapBacking = RADEONEXASharePixmapBacking; info->accel_state->exa->SetSharedPixmapBacking = RADEONEXASetSharedPixmapBacking; -#endif info->accel_state->exa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_SUPPORTS_PREPARE_AUX | EXA_HANDLES_PIXMAPS | EXA_MIXED_PIXMAPS; info->accel_state->exa->pixmapOffsetAlign = 256; diff --git a/src/radeon.h b/src/radeon.h index 319565a1..81b04ae2 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -180,11 +180,6 @@ typedef enum { } RADEONOpts; -#if XF86_CRTC_VERSION >= 5 -#define RADEON_PIXMAP_SHARING 1 -#define radeon_is_gpu_screen(screen) (screen)->isGPU -#define radeon_is_gpu_scrn(scrn) (scrn)->is_gpu - static inline ScreenPtr radeon_master_screen(ScreenPtr screen) { @@ -216,10 +211,6 @@ radeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap) #endif } -#else -#define radeon_is_gpu_screen(screen) 0 -#define radeon_is_gpu_scrn(scrn) 0 -#endif #define RADEON_VSYNC_TIMEOUT 20000 /* Maximum wait for VSYNC (in usecs) */ @@ -236,7 +227,6 @@ radeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap) #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) /* Other macros */ -#define RADEON_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) #define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1)) #define RADEONPTR(pScrn) ((RADEONInfoPtr)(pScrn)->driverPrivate) @@ -516,7 +506,7 @@ typedef struct { int Chipset; RADEONChipFamily ChipFamily; - Bool (*CloseScreen)(CLOSE_SCREEN_ARGS_DECL); + Bool (*CloseScreen)(ScreenPtr pScreen); void (*BlockHandler)(BLOCKHANDLER_ARGS_DECL); @@ -628,10 +618,8 @@ typedef struct { AddTrapsProcPtr SavedAddTraps; UnrealizeGlyphProcPtr SavedUnrealizeGlyph; #endif -#ifdef RADEON_PIXMAP_SHARING SharePixmapBackingProcPtr SavedSharePixmapBacking; SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking; -#endif } glamor; #endif /* USE_GLAMOR */ } RADEONInfoRec, *RADEONInfoPtr; diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c index 01b9e3df..0366f613 100644 --- a/src/radeon_bo_helper.c +++ b/src/radeon_bo_helper.c @@ -26,10 +26,7 @@ #include "radeon.h" #include "radeon_glamor.h" - -#ifdef RADEON_PIXMAP_SHARING #include "radeon_bo_gem.h" -#endif static const unsigned MicroBlockTable[5][3][2] = { /*linear tiled square-tiled */ @@ -89,11 +86,8 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, tiling |= RADEON_TILING_MACRO | RADEON_TILING_MICRO; if ((usage_hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP && - info->shadow_primary) -#ifdef CREATE_PIXMAP_USAGE_SHARED - || (usage_hint & 0xffff) == CREATE_PIXMAP_USAGE_SHARED -#endif - ) { + info->shadow_primary) || + (usage_hint & 0xffff) == CREATE_PIXMAP_USAGE_SHARED) { tiling = 0; domain = RADEON_GEM_DOMAIN_GTT; } @@ -299,7 +293,6 @@ uint32_t radeon_get_pixmap_tiling_flags(PixmapPtr pPix) } } -#ifdef RADEON_PIXMAP_SHARING Bool radeon_share_pixmap_backing(struct radeon_bo *bo, void **handle_p) { @@ -406,5 +399,3 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle, radeon_bo_unref(bo); return ret; } - -#endif /* RADEON_PIXMAP_SHARING */ diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 73adbe91..b569bb4f 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -42,17 +42,13 @@ #include "radeon_bo_helper.h" #include "radeon_version.h" -#include "radeon_list.h" #include "radeon_bo_gem.h" +#include #include #include -#if DRI2INFOREC_VERSION >= 9 -#define USE_DRI2_PRIME -#endif - #define FALLBACK_SWAP_DELAY 16 #include "radeon_glamor.h" @@ -283,14 +279,6 @@ error: return NULL; } -DRI2BufferPtr -radeon_dri2_create_buffer(DrawablePtr pDraw, unsigned int attachment, - unsigned int format) -{ - return radeon_dri2_create_buffer2(pDraw->pScreen, pDraw, - attachment, format); -} - static void radeon_dri2_destroy_buffer2(ScreenPtr pScreen, DrawablePtr drawable, BufferPtr buffers) @@ -321,12 +309,6 @@ radeon_dri2_destroy_buffer2(ScreenPtr pScreen, } } -void -radeon_dri2_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buf) -{ - radeon_dri2_destroy_buffer2(pDraw->pScreen, pDraw, buf); -} - static inline PixmapPtr GetDrawablePixmap(DrawablePtr drawable) { @@ -362,17 +344,14 @@ radeon_dri2_copy_region2(ScreenPtr pScreen, dst_drawable = &dst_private->pixmap->drawable; if (src_private->attachment == DRI2BufferFrontLeft) { -#ifdef USE_DRI2_PRIME if (drawable->pScreen != pScreen) { src_drawable = DRI2UpdatePrime(drawable, src_buffer); if (!src_drawable) return; } else -#endif src_drawable = drawable; } if (dst_private->attachment == DRI2BufferFrontLeft) { -#ifdef USE_DRI2_PRIME if (drawable->pScreen != pScreen) { dst_drawable = DRI2UpdatePrime(drawable, dest_buffer); if (!dst_drawable) @@ -381,7 +360,6 @@ radeon_dri2_copy_region2(ScreenPtr pScreen, if (dst_drawable != drawable) translate = TRUE; } else -#endif dst_drawable = drawable; } @@ -435,14 +413,6 @@ radeon_dri2_copy_region2(ScreenPtr pScreen, FreeScratchGC(gc); } -void -radeon_dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, - DRI2BufferPtr pDstBuffer, DRI2BufferPtr pSrcBuffer) -{ - return radeon_dri2_copy_region2(pDraw->pScreen, pDraw, pRegion, - pDstBuffer, pSrcBuffer); -} - enum DRI2FrameEventType { DRI2_SWAP, DRI2_FLIP, @@ -479,7 +449,9 @@ radeon_dri2_unref_buffer(BufferPtr buffer) { if (buffer) { struct dri2_buffer_priv *private = buffer->driverPrivate; - radeon_dri2_destroy_buffer(&(private->pixmap->drawable), buffer); + DrawablePtr draw = &private->pixmap->drawable; + + radeon_dri2_destroy_buffer2(draw->pScreen, draw, buffer); } } @@ -863,7 +835,8 @@ static void radeon_dri2_frame_event_handler(xf86CrtcPtr crtc, uint32_t seq, box.x2 = drawable->width; box.y2 = drawable->height; REGION_INIT(pScreen, ®ion, &box, 0); - radeon_dri2_copy_region(drawable, ®ion, event->front, event->back); + radeon_dri2_copy_region2(drawable->pScreen, drawable, ®ion, + event->front, event->back); swap_type = DRI2_BLIT_COMPLETE; } @@ -1394,7 +1367,7 @@ blit_fallback: box.y2 = draw->height; REGION_INIT(pScreen, ®ion, &box, 0); - radeon_dri2_copy_region(draw, ®ion, front, back); + radeon_dri2_copy_region2(draw->pScreen, draw, ®ion, front, back); DRI2SwapComplete(client, draw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data); @@ -1435,10 +1408,6 @@ radeon_dri2_screen_init(ScreenPtr pScreen) } dri2_info.fd = pRADEONEnt->fd; dri2_info.deviceName = info->dri2.device_name; - dri2_info.version = DRI2INFOREC_VERSION; - dri2_info.CreateBuffer = radeon_dri2_create_buffer; - dri2_info.DestroyBuffer = radeon_dri2_destroy_buffer; - dri2_info.CopyRegion = radeon_dri2_copy_region; if (info->dri2.pKernelDRMVersion->version_minor < 4) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel for " @@ -1467,11 +1436,10 @@ radeon_dri2_screen_init(ScreenPtr pScreen) } if (scheduling_works) { - dri2_info.version = 4; dri2_info.ScheduleSwap = radeon_dri2_schedule_swap; dri2_info.GetMSC = radeon_dri2_get_msc; dri2_info.ScheduleWaitMSC = radeon_dri2_schedule_wait_msc; - dri2_info.numDrivers = RADEON_ARRAY_SIZE(driverNames); + dri2_info.numDrivers = ARRAY_SIZE(driverNames); dri2_info.driverNames = driverNames; driverNames[0] = dri2_info.driverName; @@ -1495,12 +1463,10 @@ radeon_dri2_screen_init(ScreenPtr pScreen) DRI2InfoCnt++; } -#if DRI2INFOREC_VERSION >= 9 dri2_info.version = 9; dri2_info.CreateBuffer2 = radeon_dri2_create_buffer2; dri2_info.DestroyBuffer2 = radeon_dri2_destroy_buffer2; dri2_info.CopyRegion2 = radeon_dri2_copy_region2; -#endif info->dri2.enabled = DRI2ScreenInit(pScreen, &dri2_info); return info->dri2.enabled; diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index 37fdafeb..869f95c3 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -31,10 +31,11 @@ #endif #include +#include +#include #include "radeon.h" #include "radeon_drm_queue.h" -#include "radeon_list.h" struct radeon_drm_queue_entry { diff --git a/src/radeon_exa.c b/src/radeon_exa.c index d362e5d9..9106d5c6 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -312,7 +312,6 @@ void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv) free(driverPriv); } -#ifdef RADEON_PIXMAP_SHARING Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr slave, void **fd_handle) { struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(ppix); @@ -334,7 +333,6 @@ Bool RADEONEXASetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle) driver_priv->shared = TRUE; return TRUE; } -#endif uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix) { diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c index d9013057..da0524ed 100644 --- a/src/radeon_exa_funcs.c +++ b/src/radeon_exa_funcs.c @@ -644,10 +644,8 @@ Bool RADEONDrawInit(ScreenPtr pScreen) info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS; info->accel_state->exa->FinishAccess = RADEONFinishAccess_CS; info->accel_state->exa->CreatePixmap2 = RADEONEXACreatePixmap2; -#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 6) info->accel_state->exa->SharePixmapBacking = RADEONEXASharePixmapBacking; info->accel_state->exa->SetSharedPixmapBacking = RADEONEXASetSharedPixmapBacking; -#endif info->accel_state->exa->maxPitchBytes = 16320; diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index 01ff5609..5f378743 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -337,7 +337,6 @@ radeon_glamor_set_pixmap_bo(DrawablePtr drawable, PixmapPtr pixmap) return old; } -#ifdef RADEON_PIXMAP_SHARING static Bool radeon_glamor_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, @@ -404,7 +403,6 @@ radeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *handle) return TRUE; } -#endif /* RADEON_PIXMAP_SHARING */ Bool radeon_glamor_init(ScreenPtr screen) @@ -463,12 +461,10 @@ radeon_glamor_init(ScreenPtr screen) screen->CreatePixmap = radeon_glamor_create_pixmap; info->glamor.SavedDestroyPixmap = screen->DestroyPixmap; screen->DestroyPixmap = radeon_glamor_destroy_pixmap; -#ifdef RADEON_PIXMAP_SHARING info->glamor.SavedSharePixmapBacking = screen->SharePixmapBacking; screen->SharePixmapBacking = radeon_glamor_share_pixmap_backing; info->glamor.SavedSetSharedPixmapBacking = screen->SetSharedPixmapBacking; screen->SetSharedPixmapBacking = radeon_glamor_set_shared_pixmap_backing; -#endif xf86DrvMsg(scrn->scrnIndex, X_INFO, "Use GLAMOR acceleration.\n"); @@ -485,10 +481,8 @@ radeon_glamor_fini(ScreenPtr screen) screen->CreatePixmap = info->glamor.SavedCreatePixmap; screen->DestroyPixmap = info->glamor.SavedDestroyPixmap; -#ifdef RADEON_PIXMAP_SHARING screen->SharePixmapBacking = info->glamor.SavedSharePixmapBacking; screen->SetSharedPixmapBacking = info->glamor.SavedSetSharedPixmapBacking; -#endif } XF86VideoAdaptorPtr radeon_glamor_xv_init(ScreenPtr pScreen, int num_adapt) diff --git a/src/radeon_glamor.h b/src/radeon_glamor.h index fdc4e577..ec42df1f 100644 --- a/src/radeon_glamor.h +++ b/src/radeon_glamor.h @@ -38,10 +38,6 @@ struct radeon_pixmap; #include "radeon_surface.h" -#ifndef CREATE_PIXMAP_USAGE_SHARED -#define CREATE_PIXMAP_USAGE_SHARED RADEON_CREATE_PIXMAP_DRI2 -#endif - #define RADEON_CREATE_PIXMAP_SHARED(usage) \ (((usage) & ~RADEON_CREATE_PIXMAP_TILING_FLAGS) == RADEON_CREATE_PIXMAP_DRI2 || \ (usage) == CREATE_PIXMAP_USAGE_SHARED) diff --git a/src/radeon_glamor_wrappers.c b/src/radeon_glamor_wrappers.c index 5f165ebe..d7374252 100644 --- a/src/radeon_glamor_wrappers.c +++ b/src/radeon_glamor_wrappers.c @@ -889,7 +889,7 @@ radeon_glamor_triangles(CARD8 op, PicturePtr src, PicturePtr dst, * down our screen private, before calling down to the next CloseScreen. */ static Bool -radeon_glamor_close_screen(CLOSE_SCREEN_ARGS_DECL) +radeon_glamor_close_screen(ScreenPtr pScreen) { RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pScreen)); #ifdef RENDER @@ -917,7 +917,7 @@ radeon_glamor_close_screen(CLOSE_SCREEN_ARGS_DECL) } #endif - return (*pScreen->CloseScreen) (CLOSE_SCREEN_ARGS); + return pScreen->CloseScreen(pScreen); } /** diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 01594c6c..351af995 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -325,9 +325,7 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) if (dixPrivateKeyRegistered(rrPrivKey)) { rrScrPrivPtr rrScrPriv = rrGetScrPriv(pScreen); - if (!radeon_is_gpu_screen(pScreen) && - !rrScrPriv->primaryOutput) - { + if (!pScreen->isGPU && !rrScrPriv->primaryOutput) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); rrScrPriv->primaryOutput = xf86_config->output[0]->randr_output; @@ -336,8 +334,7 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) } } - if (!drmmode_set_desired_modes(pScrn, &info->drmmode, - radeon_is_gpu_screen(pScreen))) + if (!drmmode_set_desired_modes(pScrn, &info->drmmode, pScreen->isGPU)) return FALSE; drmmode_uevent_init(pScrn, &info->drmmode); @@ -366,8 +363,7 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) radeon_glamor_create_screen_resources(pScreen); info->callback_event_type = -1; - if (!radeon_is_gpu_screen(pScreen) && - (damage_ext = CheckExtension("DAMAGE"))) { + if (!pScreen->isGPU && (damage_ext = CheckExtension("DAMAGE"))) { info->callback_event_type = damage_ext->eventBase + XDamageNotify; if (!AddCallback(&FlushCallback, radeon_flush_callback, pScrn)) @@ -392,15 +388,12 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) static Bool radeon_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents) { -#ifdef RADEON_PIXMAP_SHARING if (xf86_crtc->scrn->is_gpu) { extents->x1 -= xf86_crtc->x; extents->y1 -= xf86_crtc->y; extents->x2 -= xf86_crtc->x; extents->y2 -= xf86_crtc->y; - } else -#endif - { + } else { extents->x1 -= xf86_crtc->filter_width >> 1; extents->x2 += xf86_crtc->filter_width >> 1; extents->y1 -= xf86_crtc->filter_height >> 1; @@ -416,8 +409,6 @@ radeon_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents) return (extents->x1 < extents->x2 && extents->y1 < extents->y2); } -#if XF86_CRTC_VERSION >= 4 - static RegionPtr transform_region(RegionPtr region, struct pict_f_transform *transform, int w, int h) @@ -456,8 +447,6 @@ transform_region(RegionPtr region, struct pict_f_transform *transform, return transformed; } -#endif - static void radeon_sync_scanout_pixmaps(xf86CrtcPtr xf86_crtc, RegionPtr new_region, int scanout_id) @@ -487,14 +476,11 @@ radeon_sync_scanout_pixmaps(xf86CrtcPtr xf86_crtc, RegionPtr new_region, if (!radeon_scanout_extents_intersect(xf86_crtc, &extents)) goto uninit; -#if XF86_CRTC_VERSION >= 4 if (xf86_crtc->driverIsPerformingTransform) { sync_region = transform_region(&remaining, &xf86_crtc->f_framebuffer_to_crtc, dst->width, dst->height); - } else -#endif /* XF86_CRTC_VERSION >= 4 */ - { + } else { sync_region = RegionDuplicate(&remaining); RegionTranslate(sync_region, -xf86_crtc->x, -xf86_crtc->y); } @@ -551,7 +537,6 @@ radeon_scanout_flip_handler(xf86CrtcPtr crtc, uint32_t msc, uint64_t usec, #endif } -#ifdef RADEON_PIXMAP_SHARING static RegionPtr dirty_region(PixmapDirtyUpdatePtr dirty) @@ -901,7 +886,7 @@ radeon_dirty_update(ScrnInfoPtr scrn) } } } -#endif + Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, @@ -932,7 +917,6 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, force = info->accel_state->force; info->accel_state->force = TRUE; -#if XF86_CRTC_VERSION >= 4 if (xf86_crtc->driverIsPerformingTransform) { SourceValidateProcPtr SourceValidate = pScreen->SourceValidate; PictFormatPtr format = PictureWindowFormat(pScreen->root); @@ -979,7 +963,6 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, FreePicture(src, None); } else out: -#endif /* XF86_CRTC_VERSION >= 4 */ { GCPtr gc = GetScratchGC(pDraw->depth, pScreen); @@ -1148,7 +1131,6 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) { - SCREEN_PTR(arg); ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); RADEONInfoPtr info = RADEONPTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); @@ -1161,7 +1143,7 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) if (!xf86ScreenToScrn(radeon_master_screen(pScreen))->vtSema) return; - if (!radeon_is_gpu_screen(pScreen)) + if (!pScreen->isGPU) { for (c = 0; c < xf86_config->num_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; @@ -1176,9 +1158,7 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) radeon_cs_flush_indirect(pScrn); -#ifdef RADEON_PIXMAP_SHARING radeon_dirty_update(pScrn); -#endif } static Bool RADEONIsFastFBWorking(ScrnInfoPtr pScrn) @@ -1618,7 +1598,6 @@ static Bool r600_get_tile_config(ScrnInfoPtr pScrn) static void RADEONSetupCapabilities(ScrnInfoPtr pScrn) { -#ifdef RADEON_PIXMAP_SHARING RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); uint64_t value; @@ -1640,7 +1619,6 @@ static void RADEONSetupCapabilities(ScrnInfoPtr pScrn) pScrn->capabilities |= RR_Capability_SinkOutput; } } -#endif } /* When the root window is created, initialize the screen contents from @@ -1853,7 +1831,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) info->tear_free == 2 ? "auto" : (info->tear_free ? "on" : "off")); } - if (!radeon_is_gpu_scrn(pScrn)) { + if (!pScrn->is_gpu) { if (info->dri2.pKernelDRMVersion->version_minor >= 8) { Bool sw_cursor = xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE); @@ -2106,7 +2084,7 @@ static void radeon_drop_drm_master(ScrnInfoPtr pScrn) * text mode, unmap video memory, and unwrap and call the saved * CloseScreen function. */ -static Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL) +static Bool RADEONCloseScreen_KMS(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); RADEONInfoPtr info = RADEONPTR(pScrn); @@ -2150,13 +2128,12 @@ static Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL) xf86ClearPrimInitDone(info->pEnt->index); pScreen->BlockHandler = info->BlockHandler; pScreen->CloseScreen = info->CloseScreen; - return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); + return pScreen->CloseScreen(pScreen); } -void RADEONFreeScreen_KMS(FREE_SCREEN_ARGS_DECL) +void RADEONFreeScreen_KMS(ScrnInfoPtr pScrn) { - SCRN_INFO_PTR(arg); RADEONInfoPtr info = RADEONPTR(pScrn); xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, @@ -2168,7 +2145,7 @@ void RADEONFreeScreen_KMS(FREE_SCREEN_ARGS_DECL) RADEONFreeRec(pScrn); } -Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) +Bool RADEONScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); @@ -2287,7 +2264,7 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) } #endif - if (!radeon_is_gpu_screen(pScreen)) { + if (!pScreen->isGPU) { if (xorgGetVersion() >= XORG_VERSION_NUMERIC(1,18,3,0,0)) value = info->use_glamor; else @@ -2370,8 +2347,7 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) */ /* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */ #endif - if (info->r600_shadow_fb == FALSE && - !radeon_is_gpu_screen(pScreen)) { + if (info->r600_shadow_fb == FALSE && !pScreen->isGPU) { /* Init Xv */ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "Initializing Xv\n"); @@ -2387,7 +2363,7 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) } pScrn->pScreen = pScreen; - if (!radeon_is_gpu_screen(pScreen)) { + if (!pScreen->isGPU) { if (serverGeneration == 1 && bgNoneRoot && info->accelOn) { info->CreateWindow = pScreen->CreateWindow; pScreen->CreateWindow = RADEONCreateWindow_oneshot; @@ -2407,12 +2383,10 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) info->CreateScreenResources = pScreen->CreateScreenResources; pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS; -#ifdef RADEON_PIXMAP_SHARING pScreen->StartPixmapTracking = PixmapStartDirtyTracking; pScreen->StopPixmapTracking = PixmapStopDirtyTracking; #if HAS_SYNC_SHARED_PIXMAP pScreen->SyncSharedPixmap = radeon_sync_shared_pixmap; -#endif #endif if (!xf86CrtcScreenInit (pScreen)) @@ -2440,9 +2414,8 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) return TRUE; } -Bool RADEONEnterVT_KMS(VT_FUNC_ARGS_DECL) +Bool RADEONEnterVT_KMS(ScrnInfoPtr pScrn) { - SCRN_INFO_PTR(arg); RADEONInfoPtr info = RADEONPTR(pScrn); xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, @@ -2497,9 +2470,8 @@ pixmap_unref_fb(void *value, XID id, void *cdata) drmmode_fb_reference(pRADEONEnt->fd, fb_ptr, NULL); } -void RADEONLeaveVT_KMS(VT_FUNC_ARGS_DECL) +void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn) { - SCRN_INFO_PTR(arg); RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); ScreenPtr pScreen = pScrn->pScreen; @@ -2595,18 +2567,16 @@ void RADEONLeaveVT_KMS(VT_FUNC_ARGS_DECL) } -Bool RADEONSwitchMode_KMS(SWITCH_MODE_ARGS_DECL) +Bool RADEONSwitchMode_KMS(ScrnInfoPtr pScrn, DisplayModePtr mode) { - SCRN_INFO_PTR(arg); Bool ret; ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0); return ret; } -void RADEONAdjustFrame_KMS(ADJUST_FRAME_ARGS_DECL) +void RADEONAdjustFrame_KMS(ScrnInfoPtr pScrn, int x, int y) { - SCRN_INFO_PTR(arg); RADEONInfoPtr info = RADEONPTR(pScrn); drmmode_adjust_frame(pScrn, &info->drmmode, x, y); return; @@ -2799,10 +2769,9 @@ void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size) } /* Used to disallow modes that are not supported by the hardware */ -ModeStatus RADEONValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, +ModeStatus RADEONValidMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool verbose, int flag) { - SCRN_INFO_PTR(arg); RADEONInfoPtr info = RADEONPTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); diff --git a/src/radeon_list.h b/src/radeon_list.h deleted file mode 100644 index f9e4ff73..00000000 --- a/src/radeon_list.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright © 2015 Advanced Micro Devices, Inc. - * - * 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 _RADEON_LIST_H_ -#define _RADEON_LIST_H_ - -#include -#include - -#if !HAVE_XORG_LIST -#define xorg_list list -#define xorg_list_init list_init -#define xorg_list_is_empty list_is_empty -#define xorg_list_add list_add -#define xorg_list_del list_del -#define xorg_list_for_each_entry list_for_each_entry -#define xorg_list_for_each_entry_safe list_for_each_entry_safe - -static inline void -xorg_list_append(struct list *entry, struct list *head) -{ - __list_add(entry, head->prev, head); -} - -#endif - -#endif /* _RADEON_LIST_H_ */ diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 9e50c811..be82f9ae 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -151,13 +151,13 @@ typedef struct extern const OptionInfoRec *RADEONOptionsWeak(void); extern Bool RADEONPreInit_KMS(ScrnInfoPtr, int); -extern Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL); -extern Bool RADEONSwitchMode_KMS(SWITCH_MODE_ARGS_DECL); -extern void RADEONAdjustFrame_KMS(ADJUST_FRAME_ARGS_DECL); -extern Bool RADEONEnterVT_KMS(VT_FUNC_ARGS_DECL); -extern void RADEONLeaveVT_KMS(VT_FUNC_ARGS_DECL); -extern void RADEONFreeScreen_KMS(FREE_SCREEN_ARGS_DECL); +extern Bool RADEONScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv); +extern Bool RADEONSwitchMode_KMS(ScrnInfoPtr pScrn, DisplayModePtr mode); +extern void RADEONAdjustFrame_KMS(ScrnInfoPtr pScrn, int x, int y); +extern Bool RADEONEnterVT_KMS(ScrnInfoPtr pScrn); +extern void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn); +extern void RADEONFreeScreen_KMS(ScrnInfoPtr pScrn); -extern ModeStatus RADEONValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, - Bool verbose, int flag); +extern ModeStatus RADEONValidMode(ScrnInfoPtr pScrn, DisplayModePtr mode, + Bool verbose, int flag); #endif /* _RADEON_PROBE_H_ */ -- cgit v1.2.3 From f9aca8c1a7a423b9e738c88400ae821bdfbcdb1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 8 Sep 2017 17:02:59 +0900 Subject: Bump version for 7.10.0 release --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 9c595f8b..dfb60a83 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [7.9.99], + [7.10.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon], [xf86-video-ati]) -- cgit v1.2.3 From 34da04daec82077571558ac3fe1ec0c1203a01ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 3 Oct 2017 12:47:14 +0200 Subject: Fix VT switching with ShadowFB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were trying to call acceleration specific functions from LeaveVT. Instead, memset the scanout buffer to all 0 in LeaveVT and allocate a new one in EnterVT. Bugzilla: https://bugs.freedesktop.org/102948 Fixes: 06a465484101 ("Make all active CRTCs scan out an all-black framebuffer in LeaveVT") Signed-off-by: Michel Dänzer Reviewed-by: Alex Deucher --- src/radeon_kms.c | 157 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 94 insertions(+), 63 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 351af995..b982e425 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2423,6 +2423,31 @@ Bool RADEONEnterVT_KMS(ScrnInfoPtr pScrn) radeon_set_drm_master(pScrn); + if (info->r600_shadow_fb) { + int base_align = drmmode_get_base_align(pScrn, info->pixel_bytes, 0); + struct radeon_bo *front_bo = radeon_bo_open(info->bufmgr, 0, + info->front_bo->size, + base_align, + RADEON_GEM_DOMAIN_VRAM, 0); + + if (front_bo) { + if (radeon_bo_map(front_bo, 1) == 0) { + memset(front_bo->ptr, 0, front_bo->size); + radeon_bo_unref(info->front_bo); + info->front_bo = front_bo; + } else { + radeon_bo_unref(front_bo); + front_bo = NULL; + } + } + + if (!front_bo) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate new scanout BO after VT switch, " + "other DRM masters may see screen contents\n"); + } + } + info->accel_state->XInited3D = FALSE; info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; @@ -2473,85 +2498,91 @@ pixmap_unref_fb(void *value, XID id, void *cdata) void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); ScreenPtr pScreen = pScrn->pScreen; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - struct drmmode_scanout black_scanout = { .pixmap = NULL, .bo = NULL }; - xf86CrtcPtr crtc; - drmmode_crtc_private_ptr drmmode_crtc; - unsigned w = 0, h = 0; - int i; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONLeaveVT_KMS\n"); - /* Compute maximum scanout dimensions of active CRTCs */ - for (i = 0; i < xf86_config->num_crtc; i++) { - crtc = xf86_config->crtc[i]; - drmmode_crtc = crtc->driver_private; + if (!info->r600_shadow_fb) { + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + struct drmmode_scanout black_scanout = { .pixmap = NULL, .bo = NULL }; + xf86CrtcPtr crtc; + drmmode_crtc_private_ptr drmmode_crtc; + unsigned w = 0, h = 0; + int i; - if (!drmmode_crtc->fb) - continue; + /* Compute maximum scanout dimensions of active CRTCs */ + for (i = 0; i < xf86_config->num_crtc; i++) { + crtc = xf86_config->crtc[i]; + drmmode_crtc = crtc->driver_private; - w = max(w, crtc->mode.HDisplay); - h = max(h, crtc->mode.VDisplay); - } - - /* Make all active CRTCs scan out from an all-black framebuffer */ - if (w > 0 && h > 0) { - if (drmmode_crtc_scanout_create(crtc, &black_scanout, w, h)) { - struct drmmode_fb *black_fb = - radeon_pixmap_get_fb(black_scanout.pixmap); - - radeon_pixmap_clear(black_scanout.pixmap); - radeon_cs_flush_indirect(pScrn); - radeon_bo_wait(black_scanout.bo); - - for (i = 0; i < xf86_config->num_crtc; i++) { - crtc = xf86_config->crtc[i]; - drmmode_crtc = crtc->driver_private; - - if (drmmode_crtc->fb) { - if (black_fb) { - drmmode_set_mode(crtc, black_fb, &crtc->mode, 0, 0); - } else { - drmModeSetCrtc(pRADEONEnt->fd, - drmmode_crtc->mode_crtc->crtc_id, 0, 0, - 0, NULL, 0, NULL); - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, - NULL); - } + if (!drmmode_crtc->fb) + continue; + + w = max(w, crtc->mode.HDisplay); + h = max(h, crtc->mode.VDisplay); + } + + /* Make all active CRTCs scan out from an all-black framebuffer */ + if (w > 0 && h > 0) { + if (drmmode_crtc_scanout_create(crtc, &black_scanout, w, h)) { + struct drmmode_fb *black_fb = + radeon_pixmap_get_fb(black_scanout.pixmap); + + radeon_pixmap_clear(black_scanout.pixmap); + radeon_cs_flush_indirect(pScrn); + radeon_bo_wait(black_scanout.bo); + + for (i = 0; i < xf86_config->num_crtc; i++) { + crtc = xf86_config->crtc[i]; + drmmode_crtc = crtc->driver_private; + + if (drmmode_crtc->fb) { + if (black_fb) { + drmmode_set_mode(crtc, black_fb, &crtc->mode, 0, 0); + } else { + drmModeSetCrtc(pRADEONEnt->fd, + drmmode_crtc->mode_crtc->crtc_id, 0, + 0, 0, NULL, 0, NULL); + drmmode_fb_reference(pRADEONEnt->fd, + &drmmode_crtc->fb, NULL); + } - if (pScrn->is_gpu) { - if (drmmode_crtc->scanout[0].pixmap) - pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap, - None, pRADEONEnt); - if (drmmode_crtc->scanout[1].pixmap) - pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap, - None, pRADEONEnt); - } else { - drmmode_crtc_scanout_free(drmmode_crtc); + if (pScrn->is_gpu) { + if (drmmode_crtc->scanout[0].pixmap) + pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap, + None, pRADEONEnt); + if (drmmode_crtc->scanout[1].pixmap) + pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap, + None, pRADEONEnt); + } else { + drmmode_crtc_scanout_free(drmmode_crtc); + } } } } } - } - xf86RotateFreeShadow(pScrn); - drmmode_crtc_scanout_destroy(&info->drmmode, &black_scanout); + xf86RotateFreeShadow(pScrn); + drmmode_crtc_scanout_destroy(&info->drmmode, &black_scanout); - /* Unreference FBs of all pixmaps. After this, the only FB remaining - * should be the all-black one being scanned out by active CRTCs - */ - for (i = 0; i < currentMaxClients; i++) { - if (i > 0 && - (!clients[i] || clients[i]->clientState != ClientStateRunning)) - continue; + /* Unreference FBs of all pixmaps. After this, the only FB remaining + * should be the all-black one being scanned out by active CRTCs + */ + for (i = 0; i < currentMaxClients; i++) { + if (i > 0 && + (!clients[i] || clients[i]->clientState != ClientStateRunning)) + continue; + + FindClientResourcesByType(clients[i], RT_PIXMAP, pixmap_unref_fb, + pRADEONEnt); + } - FindClientResourcesByType(clients[i], RT_PIXMAP, pixmap_unref_fb, - pRADEONEnt); + pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pRADEONEnt); + } else { + memset(info->front_bo->ptr, 0, info->front_bo->size); } - pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pRADEONEnt); TimerSet(NULL, 0, 1000, cleanup_black_fb, pScreen); -- cgit v1.2.3 From b71836c9962f8f2eadf0c2188e03faed737c18da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 4 Oct 2017 11:05:49 +0200 Subject: Post-release version bump --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index dfb60a83..a11ba2a4 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [7.10.0], + [7.10.99], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon], [xf86-video-ati]) -- cgit v1.2.3 From 7d435354099119234d443b07e2df1c7b9f97cf3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 4 Oct 2017 11:11:33 +0200 Subject: Bail if there's a problem with ShadowFB If we hit a problem while setting up ShadowFB, just carrying on trying to set up HW acceleration instead is unlikely to work. Reviewed-by: Alex Deucher --- src/radeon_kms.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index b982e425..9ef51693 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1331,9 +1331,10 @@ static Bool RADEONPreInitAccel_KMS(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GPU accel disabled or not working, using shadowfb for KMS\n"); shadowfb: - info->r600_shadow_fb = TRUE; if (!xf86LoadSubModule(pScrn, "shadow")) - info->r600_shadow_fb = FALSE; + return FALSE; + + info->r600_shadow_fb = TRUE; return TRUE; } @@ -2215,7 +2216,7 @@ Bool RADEONScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv) if (info->fb_shadow == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate shadow framebuffer\n"); - info->r600_shadow_fb = FALSE; + return FALSE; } else { if (!fbScreenInit(pScreen, info->fb_shadow, pScrn->virtualX, pScrn->virtualY, -- cgit v1.2.3 From 61113768bd79ec5c2164835e2e048e8f2a42ce9a Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Thu, 19 Oct 2017 18:17:07 +0200 Subject: Clarify when TearFree is automatically enabled. (Ported from amdgpu commit 2f72be038d22c54620e436af30121dd89f79a003) Reviewed-by: Alex Deucher --- man/radeon.man | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man/radeon.man b/man/radeon.man index 9fd863f3..f4441c4b 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -288,8 +288,8 @@ separate scanout buffers need to be allocated for each CRTC with TearFree on. If this option is set, the default value of the property is 'on' or 'off' accordingly. If this option isn't set, the default value of the property is .B auto, -which means that TearFree is on for outputs with rotation or other RandR -transforms, and for RandR 1.4 slave outputs, otherwise off. +which means that TearFree is on for rotated outputs, outputs with RandR +transforms applied and for RandR 1.4 slave outputs, otherwise off. .TP .BI "Option \*qAccelMethod\*q \*q" "string" \*q Chooses between available acceleration architectures. Valid values are -- cgit v1.2.3 From b93ae9b159790e8a979e9d5d567a0e6fccd7d08a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 19 Oct 2017 18:57:45 +0200 Subject: Unreference pixmap's FB with EXA as well in radeon_set_pixmap_bo Not doing so resulted in DRI2 page flips not actually changing the FB being scanned out, showing intermittent flicker of the "back" buffer rendering. Bugzilla: https://bugs.freedesktop.org/102643 Fixes: 55e513b978b2 "Use reference counting for tracking KMS framebuffer lifetimes" Reviewed-by: Alex Deucher --- src/radeon.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/radeon.h b/src/radeon.h index 81b04ae2..d54e4990 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -769,6 +769,8 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) if (driver_priv->bo) radeon_bo_unref(driver_priv->bo); + drmmode_fb_reference(pRADEONEnt->fd, &driver_priv->fb, NULL); + radeon_bo_ref(bo); driver_priv->bo = bo; -- cgit v1.2.3