diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2011-01-10 18:16:49 -0500 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2011-01-10 18:16:49 -0500 |
commit | e5d0a400d08da2358fac9c2ad12042f125525736 (patch) | |
tree | a869dd4be87331d24076cc46c60ef4dffbb5b9f2 | |
parent | 0e432dff9e06a183acaeb20db29cbd03ff0f4b82 (diff) | |
parent | e27e9b4e50ad42885ad2e25be897cdf29aa59712 (diff) |
Merge branch 'kms-pflip' of git+ssh://git.freedesktop.org/git/xorg/driver/xf86-video-ati
-rw-r--r-- | man/radeon.man | 17 | ||||
-rw-r--r-- | src/drmmode_display.c | 134 | ||||
-rw-r--r-- | src/drmmode_display.h | 12 | ||||
-rw-r--r-- | src/evergreen_exa.c | 21 | ||||
-rw-r--r-- | src/r600_exa.c | 21 | ||||
-rw-r--r-- | src/radeon.h | 8 | ||||
-rw-r--r-- | src/radeon_dri2.c | 278 | ||||
-rw-r--r-- | src/radeon_dri2.h | 2 | ||||
-rw-r--r-- | src/radeon_exa.c | 11 | ||||
-rw-r--r-- | src/radeon_kms.c | 23 |
10 files changed, 461 insertions, 66 deletions
diff --git a/man/radeon.man b/man/radeon.man index 609f7672..285cb397 100644 --- a/man/radeon.man +++ b/man/radeon.man | |||
@@ -266,7 +266,22 @@ to use VRAM for non-essential pixmaps. This option allows us to override the | |||
266 | heuristic. The default is | 266 | heuristic. The default is |
267 | .B on | 267 | .B on |
268 | with > 32MB VRAM, off with < 32MB. | 268 | with > 32MB VRAM, off with < 32MB. |
269 | 269 | .TP | |
270 | .BI "Option \*qSwapbuffersWait\*q \*q" boolean \*q | ||
271 | This option controls the behavior of glXSwapBuffers and glXCopySubBufferMESA | ||
272 | calls by GL applications. If enabled, the calls will avoid tearing by making | ||
273 | sure the display scanline is outside of the area to be copied before the copy | ||
274 | occurs. If disabled, no scanline synchronization is performed, meaning tearing | ||
275 | will likely occur. Note that when enabled, this option can adversely affect | ||
276 | the framerate of applications that render frames at less than refresh rate. | ||
277 | .IP | ||
278 | The default value is | ||
279 | .B on. | ||
280 | .TP | ||
281 | .BI "Option \*qEnablePageFlip\*q \*q" boolean \*q | ||
282 | Enable DRI2 page flipping. The default is | ||
283 | .B on. | ||
284 | Pageflipping is supported on all radeon hardware. | ||
270 | .PP | 285 | .PP |
271 | The following driver | 286 | The following driver |
272 | .B Options | 287 | .B Options |
diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 0a6e338e..9248cb0e 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "config.h" | 29 | #include "config.h" |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | #include <errno.h> | ||
32 | #ifdef XF86DRM_MODE | 33 | #ifdef XF86DRM_MODE |
33 | #include <sys/ioctl.h> | 34 | #include <sys/ioctl.h> |
34 | #include "micmap.h" | 35 | #include "micmap.h" |
@@ -266,9 +267,10 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, | |||
266 | uint32_t tiling_flags = 0; | 267 | uint32_t tiling_flags = 0; |
267 | int height; | 268 | int height; |
268 | 269 | ||
269 | /* no tiled scanout on r6xx+ yet */ | ||
270 | if (info->allowColorTiling) { | 270 | if (info->allowColorTiling) { |
271 | if (info->ChipFamily < CHIP_FAMILY_R600) | 271 | if (info->ChipFamily >= CHIP_FAMILY_R600) |
272 | tiling_flags |= RADEON_TILING_MICRO; | ||
273 | else | ||
272 | tiling_flags |= RADEON_TILING_MACRO; | 274 | tiling_flags |= RADEON_TILING_MACRO; |
273 | } | 275 | } |
274 | 276 | ||
@@ -1167,9 +1169,10 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) | |||
1167 | if (front_bo) | 1169 | if (front_bo) |
1168 | radeon_bo_wait(front_bo); | 1170 | radeon_bo_wait(front_bo); |
1169 | 1171 | ||
1170 | /* no tiled scanout on r6xx+ yet */ | ||
1171 | if (info->allowColorTiling) { | 1172 | if (info->allowColorTiling) { |
1172 | if (info->ChipFamily < CHIP_FAMILY_R600) | 1173 | if (info->ChipFamily >= CHIP_FAMILY_R600) |
1174 | tiling_flags |= RADEON_TILING_MICRO; | ||
1175 | else | ||
1173 | tiling_flags |= RADEON_TILING_MACRO; | 1176 | tiling_flags |= RADEON_TILING_MACRO; |
1174 | } | 1177 | } |
1175 | 1178 | ||
@@ -1278,6 +1281,39 @@ drmmode_vblank_handler(int fd, unsigned int frame, unsigned int tv_sec, | |||
1278 | } | 1281 | } |
1279 | 1282 | ||
1280 | static void | 1283 | static void |
1284 | drmmode_flip_handler(int fd, unsigned int frame, unsigned int tv_sec, | ||
1285 | unsigned int tv_usec, void *event_data) | ||
1286 | { | ||
1287 | drmmode_flipevtcarrier_ptr flipcarrier = event_data; | ||
1288 | drmmode_ptr drmmode = flipcarrier->drmmode; | ||
1289 | |||
1290 | /* Is this the event whose info shall be delivered to higher level? */ | ||
1291 | if (flipcarrier->dispatch_me) { | ||
1292 | /* Yes: Cache msc, ust for later delivery. */ | ||
1293 | drmmode->fe_frame = frame; | ||
1294 | drmmode->fe_tv_sec = tv_sec; | ||
1295 | drmmode->fe_tv_usec = tv_usec; | ||
1296 | } | ||
1297 | free(flipcarrier); | ||
1298 | |||
1299 | /* Last crtc completed flip? */ | ||
1300 | drmmode->flip_count--; | ||
1301 | if (drmmode->flip_count > 0) | ||
1302 | return; | ||
1303 | |||
1304 | /* Release framebuffer */ | ||
1305 | drmModeRmFB(drmmode->fd, drmmode->old_fb_id); | ||
1306 | |||
1307 | if (drmmode->event_data == NULL) | ||
1308 | return; | ||
1309 | |||
1310 | /* Deliver cached msc, ust from reference crtc to flip event handler */ | ||
1311 | radeon_dri2_flip_event_handler(drmmode->fe_frame, drmmode->fe_tv_sec, | ||
1312 | drmmode->fe_tv_usec, drmmode->event_data); | ||
1313 | } | ||
1314 | |||
1315 | |||
1316 | static void | ||
1281 | drm_wakeup_handler(pointer data, int err, pointer p) | 1317 | drm_wakeup_handler(pointer data, int err, pointer p) |
1282 | { | 1318 | { |
1283 | drmmode_ptr drmmode = data; | 1319 | drmmode_ptr drmmode = data; |
@@ -1320,8 +1356,9 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) | |||
1320 | drmmode->flip_count = 0; | 1356 | drmmode->flip_count = 0; |
1321 | drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION; | 1357 | drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION; |
1322 | drmmode->event_context.vblank_handler = drmmode_vblank_handler; | 1358 | drmmode->event_context.vblank_handler = drmmode_vblank_handler; |
1323 | drmmode->event_context.page_flip_handler = NULL; | 1359 | drmmode->event_context.page_flip_handler = drmmode_flip_handler; |
1324 | if (!pRADEONEnt->fd_wakeup_registered && info->dri->pKernelDRMVersion->version_minor >= 4) { | 1360 | if (!pRADEONEnt->fd_wakeup_registered && info->dri->pKernelDRMVersion->version_minor >= 4) { |
1361 | drmmode->flip_count = 0; | ||
1325 | AddGeneralSocket(drmmode->fd); | 1362 | AddGeneralSocket(drmmode->fd); |
1326 | RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, | 1363 | RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, |
1327 | drm_wakeup_handler, drmmode); | 1364 | drm_wakeup_handler, drmmode); |
@@ -1561,4 +1598,91 @@ void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode) | |||
1561 | #endif | 1598 | #endif |
1562 | } | 1599 | } |
1563 | 1600 | ||
1601 | Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *data, int ref_crtc_hw_id) | ||
1602 | { | ||
1603 | RADEONInfoPtr info = RADEONPTR(scrn); | ||
1604 | xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); | ||
1605 | drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private; | ||
1606 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | ||
1607 | unsigned int pitch = scrn->displayWidth * info->CurrentLayout.pixel_bytes; | ||
1608 | int i, old_fb_id; | ||
1609 | uint32_t tiling_flags = 0; | ||
1610 | int height; | ||
1611 | drmmode_flipevtcarrier_ptr flipcarrier; | ||
1612 | |||
1613 | if (info->allowColorTiling) { | ||
1614 | if (info->ChipFamily >= CHIP_FAMILY_R600) | ||
1615 | tiling_flags |= RADEON_TILING_MICRO; | ||
1616 | else | ||
1617 | tiling_flags |= RADEON_TILING_MACRO; | ||
1618 | } | ||
1619 | |||
1620 | pitch = RADEON_ALIGN(pitch, drmmode_get_pitch_align(scrn, info->CurrentLayout.pixel_bytes, tiling_flags)); | ||
1621 | height = RADEON_ALIGN(scrn->virtualY, drmmode_get_height_align(scrn, tiling_flags)); | ||
1622 | |||
1623 | /* | ||
1624 | * Create a new handle for the back buffer | ||
1625 | */ | ||
1626 | old_fb_id = drmmode->fb_id; | ||
1627 | if (drmModeAddFB(drmmode->fd, scrn->virtualX, height, | ||
1628 | scrn->depth, scrn->bitsPerPixel, pitch, | ||
1629 | new_front->handle, &drmmode->fb_id)) | ||
1630 | goto error_out; | ||
1631 | |||
1632 | /* | ||
1633 | * Queue flips on all enabled CRTCs | ||
1634 | * Note that if/when we get per-CRTC buffers, we'll have to update this. | ||
1635 | * Right now it assumes a single shared fb across all CRTCs, with the | ||
1636 | * kernel fixing up the offset of each CRTC as necessary. | ||
1637 | * | ||
1638 | * Also, flips queued on disabled or incorrectly configured displays | ||
1639 | * may never complete; this is a configuration error. | ||
1640 | */ | ||
1641 | drmmode->fe_frame = 0; | ||
1642 | drmmode->fe_tv_sec = 0; | ||
1643 | drmmode->fe_tv_usec = 0; | ||
1644 | |||
1645 | for (i = 0; i < config->num_crtc; i++) { | ||
1646 | if (!config->crtc[i]->enabled) | ||
1647 | continue; | ||
1648 | |||
1649 | drmmode->event_data = data; | ||
1650 | drmmode->flip_count++; | ||
1651 | drmmode_crtc = config->crtc[i]->driver_private; | ||
1652 | |||
1653 | flipcarrier = calloc(1, sizeof(drmmode_flipevtcarrier_rec)); | ||
1654 | if (!flipcarrier) { | ||
1655 | xf86DrvMsg(scrn->scrnIndex, X_WARNING, | ||
1656 | "flip queue: carrier alloc failed.\n"); | ||
1657 | goto error_undo; | ||
1658 | } | ||
1659 | |||
1660 | /* Only the reference crtc will finally deliver its page flip | ||
1661 | * completion event. All other crtc's events will be discarded. | ||
1662 | */ | ||
1663 | flipcarrier->dispatch_me = (drmmode_crtc->hw_id == ref_crtc_hw_id); | ||
1664 | flipcarrier->drmmode = drmmode; | ||
1665 | |||
1666 | if (drmModePageFlip(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, | ||
1667 | drmmode->fb_id, DRM_MODE_PAGE_FLIP_EVENT, flipcarrier)) { | ||
1668 | xf86DrvMsg(scrn->scrnIndex, X_WARNING, | ||
1669 | "flip queue failed: %s\n", strerror(errno)); | ||
1670 | free(flipcarrier); | ||
1671 | goto error_undo; | ||
1672 | } | ||
1673 | } | ||
1674 | |||
1675 | drmmode->old_fb_id = old_fb_id; | ||
1676 | return TRUE; | ||
1677 | |||
1678 | error_undo: | ||
1679 | drmModeRmFB(drmmode->fd, drmmode->fb_id); | ||
1680 | drmmode->fb_id = old_fb_id; | ||
1681 | |||
1682 | error_out: | ||
1683 | xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n", | ||
1684 | strerror(errno)); | ||
1685 | return FALSE; | ||
1686 | } | ||
1687 | |||
1564 | #endif | 1688 | #endif |
diff --git a/src/drmmode_display.h b/src/drmmode_display.h index e6bfd50a..548907bb 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h | |||
@@ -39,6 +39,7 @@ | |||
39 | typedef struct { | 39 | typedef struct { |
40 | int fd; | 40 | int fd; |
41 | unsigned fb_id; | 41 | unsigned fb_id; |
42 | unsigned old_fb_id; | ||
42 | drmModeResPtr mode_res; | 43 | drmModeResPtr mode_res; |
43 | drmModeFBPtr mode_fb; | 44 | drmModeFBPtr mode_fb; |
44 | int cpp; | 45 | int cpp; |
@@ -50,9 +51,18 @@ typedef struct { | |||
50 | #endif | 51 | #endif |
51 | drmEventContext event_context; | 52 | drmEventContext event_context; |
52 | int flip_count; | 53 | int flip_count; |
54 | void *event_data; | ||
55 | unsigned int fe_frame; | ||
56 | unsigned int fe_tv_sec; | ||
57 | unsigned int fe_tv_usec; | ||
53 | } drmmode_rec, *drmmode_ptr; | 58 | } drmmode_rec, *drmmode_ptr; |
54 | 59 | ||
55 | typedef struct { | 60 | typedef struct { |
61 | drmmode_ptr drmmode; | ||
62 | Bool dispatch_me; | ||
63 | } drmmode_flipevtcarrier_rec, *drmmode_flipevtcarrier_ptr; | ||
64 | |||
65 | typedef struct { | ||
56 | drmmode_ptr drmmode; | 66 | drmmode_ptr drmmode; |
57 | drmModeCrtcPtr mode_crtc; | 67 | drmModeCrtcPtr mode_crtc; |
58 | int hw_id; | 68 | int hw_id; |
@@ -99,6 +109,8 @@ extern int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling); | |||
99 | extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); | 109 | extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); |
100 | extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); | 110 | extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); |
101 | 111 | ||
112 | Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *data, int ref_crtc_hw_id); | ||
113 | |||
102 | #endif | 114 | #endif |
103 | 115 | ||
104 | #endif | 116 | #endif |
diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c index c6ef33d4..0fe00d80 100644 --- a/src/evergreen_exa.c +++ b/src/evergreen_exa.c | |||
@@ -1647,22 +1647,29 @@ EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, | |||
1647 | Bool flush = FALSE; | 1647 | Bool flush = FALSE; |
1648 | Bool r; | 1648 | Bool r; |
1649 | struct r600_accel_object src_obj, dst_obj; | 1649 | struct r600_accel_object src_obj, dst_obj; |
1650 | uint32_t tiling_flags = 0, pitch = 0; | ||
1650 | 1651 | ||
1651 | if (bpp < 8) | 1652 | if (bpp < 8) |
1652 | return FALSE; | 1653 | return FALSE; |
1653 | 1654 | ||
1654 | driver_priv = exaGetPixmapDriverPrivate(pSrc); | 1655 | driver_priv = exaGetPixmapDriverPrivate(pSrc); |
1655 | 1656 | ||
1657 | ret = radeon_bo_get_tiling(driver_priv->bo, &tiling_flags, &pitch); | ||
1658 | if (ret) | ||
1659 | ErrorF("radeon_bo_get_tiling failed\n"); | ||
1660 | |||
1656 | /* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */ | 1661 | /* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */ |
1657 | copy_src = driver_priv->bo; | 1662 | copy_src = driver_priv->bo; |
1658 | copy_pitch = pSrc->devKind; | 1663 | copy_pitch = pSrc->devKind; |
1659 | if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { | 1664 | if (!(tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) { |
1660 | src_domain = radeon_bo_get_src_domain(driver_priv->bo); | 1665 | if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { |
1661 | if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == | 1666 | src_domain = radeon_bo_get_src_domain(driver_priv->bo); |
1662 | (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) | 1667 | if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == |
1663 | src_domain = 0; | 1668 | (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) |
1664 | else /* A write may be scheduled */ | 1669 | src_domain = 0; |
1665 | flush = TRUE; | 1670 | else /* A write may be scheduled */ |
1671 | flush = TRUE; | ||
1672 | } | ||
1666 | } | 1673 | } |
1667 | 1674 | ||
1668 | if (!src_domain) | 1675 | if (!src_domain) |
diff --git a/src/r600_exa.c b/src/r600_exa.c index 15db42ac..5dfc770e 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c | |||
@@ -1895,22 +1895,29 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, | |||
1895 | Bool flush = FALSE; | 1895 | Bool flush = FALSE; |
1896 | Bool r; | 1896 | Bool r; |
1897 | struct r600_accel_object src_obj, dst_obj; | 1897 | struct r600_accel_object src_obj, dst_obj; |
1898 | uint32_t tiling_flags = 0, pitch = 0; | ||
1898 | 1899 | ||
1899 | if (bpp < 8) | 1900 | if (bpp < 8) |
1900 | return FALSE; | 1901 | return FALSE; |
1901 | 1902 | ||
1902 | driver_priv = exaGetPixmapDriverPrivate(pSrc); | 1903 | driver_priv = exaGetPixmapDriverPrivate(pSrc); |
1903 | 1904 | ||
1905 | ret = radeon_bo_get_tiling(driver_priv->bo, &tiling_flags, &pitch); | ||
1906 | if (ret) | ||
1907 | ErrorF("radeon_bo_get_tiling failed\n"); | ||
1908 | |||
1904 | /* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */ | 1909 | /* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */ |
1905 | copy_src = driver_priv->bo; | 1910 | copy_src = driver_priv->bo; |
1906 | copy_pitch = pSrc->devKind; | 1911 | copy_pitch = pSrc->devKind; |
1907 | if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { | 1912 | if (!(tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) { |
1908 | src_domain = radeon_bo_get_src_domain(driver_priv->bo); | 1913 | if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { |
1909 | if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == | 1914 | src_domain = radeon_bo_get_src_domain(driver_priv->bo); |
1910 | (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) | 1915 | if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == |
1911 | src_domain = 0; | 1916 | (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) |
1912 | else /* A write may be scheduled */ | 1917 | src_domain = 0; |
1913 | flush = TRUE; | 1918 | else /* A write may be scheduled */ |
1919 | flush = TRUE; | ||
1920 | } | ||
1914 | } | 1921 | } |
1915 | 1922 | ||
1916 | if (!src_domain) | 1923 | if (!src_domain) |
diff --git a/src/radeon.h b/src/radeon.h index 7f55feec..4da9bf76 100644 --- a/src/radeon.h +++ b/src/radeon.h | |||
@@ -224,7 +224,8 @@ typedef enum { | |||
224 | OPTION_FORCE_LOW_POWER, | 224 | OPTION_FORCE_LOW_POWER, |
225 | OPTION_DYNAMIC_PM, | 225 | OPTION_DYNAMIC_PM, |
226 | OPTION_NEW_PLL, | 226 | OPTION_NEW_PLL, |
227 | OPTION_ZAPHOD_HEADS | 227 | OPTION_ZAPHOD_HEADS, |
228 | OPTION_SWAPBUFFERS_WAIT | ||
228 | } RADEONOpts; | 229 | } RADEONOpts; |
229 | 230 | ||
230 | 231 | ||
@@ -1079,6 +1080,11 @@ typedef struct { | |||
1079 | struct radeon_bo *bicubic_bo; | 1080 | struct radeon_bo *bicubic_bo; |
1080 | void *bicubic_memory; | 1081 | void *bicubic_memory; |
1081 | int bicubic_offset; | 1082 | int bicubic_offset; |
1083 | /* kms pageflipping */ | ||
1084 | Bool allowPageFlip; | ||
1085 | |||
1086 | /* Perform vsync'ed SwapBuffers? */ | ||
1087 | Bool swapBuffersWait; | ||
1082 | } RADEONInfoRec, *RADEONInfoPtr; | 1088 | } RADEONInfoRec, *RADEONInfoPtr; |
1083 | 1089 | ||
1084 | #define RADEONWaitForFifo(pScrn, entries) \ | 1090 | #define RADEONWaitForFifo(pScrn, entries) \ |
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index f2ea0bb4..e8e16ff9 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c | |||
@@ -82,6 +82,10 @@ radeon_dri2_create_buffers(DrawablePtr drawable, | |||
82 | struct radeon_exa_pixmap_priv *driver_priv; | 82 | struct radeon_exa_pixmap_priv *driver_priv; |
83 | int i, r, need_enlarge = 0; | 83 | int i, r, need_enlarge = 0; |
84 | int flags = 0; | 84 | int flags = 0; |
85 | unsigned front_width; | ||
86 | |||
87 | pixmap = screen->GetScreenPixmap(screen); | ||
88 | front_width = pixmap->drawable.width; | ||
85 | 89 | ||
86 | buffers = calloc(count, sizeof *buffers); | 90 | buffers = calloc(count, sizeof *buffers); |
87 | if (buffers == NULL) { | 91 | if (buffers == NULL) { |
@@ -162,12 +166,18 @@ radeon_dri2_create_buffers(DrawablePtr drawable, | |||
162 | drawable->depth, | 166 | drawable->depth, |
163 | flags); | 167 | flags); |
164 | 168 | ||
165 | } else | 169 | } else { |
170 | unsigned aligned_width = drawable->width; | ||
171 | |||
172 | if (aligned_width == front_width) | ||
173 | aligned_width = pScrn->virtualX; | ||
174 | |||
166 | pixmap = (*pScreen->CreatePixmap)(pScreen, | 175 | pixmap = (*pScreen->CreatePixmap)(pScreen, |
167 | drawable->width, | 176 | aligned_width, |
168 | drawable->height, | 177 | drawable->height, |
169 | drawable->depth, | 178 | drawable->depth, |
170 | flags); | 179 | flags); |
180 | } | ||
171 | } | 181 | } |
172 | 182 | ||
173 | if (attachments[i] == DRI2BufferDepth) { | 183 | if (attachments[i] == DRI2BufferDepth) { |
@@ -206,6 +216,10 @@ radeon_dri2_create_buffer(DrawablePtr drawable, | |||
206 | struct radeon_exa_pixmap_priv *driver_priv; | 216 | struct radeon_exa_pixmap_priv *driver_priv; |
207 | int r, need_enlarge = 0; | 217 | int r, need_enlarge = 0; |
208 | int flags; | 218 | int flags; |
219 | unsigned front_width; | ||
220 | |||
221 | pixmap = pScreen->GetScreenPixmap(pScreen); | ||
222 | front_width = pixmap->drawable.width; | ||
209 | 223 | ||
210 | buffers = calloc(1, sizeof *buffers); | 224 | buffers = calloc(1, sizeof *buffers); |
211 | if (buffers == NULL) { | 225 | if (buffers == NULL) { |
@@ -287,12 +301,18 @@ radeon_dri2_create_buffer(DrawablePtr drawable, | |||
287 | (format != 0)?format:drawable->depth, | 301 | (format != 0)?format:drawable->depth, |
288 | flags); | 302 | flags); |
289 | 303 | ||
290 | } else | 304 | } else { |
305 | unsigned aligned_width = drawable->width; | ||
306 | |||
307 | if (aligned_width == front_width) | ||
308 | aligned_width = pScrn->virtualX; | ||
309 | |||
291 | pixmap = (*pScreen->CreatePixmap)(pScreen, | 310 | pixmap = (*pScreen->CreatePixmap)(pScreen, |
292 | drawable->width, | 311 | aligned_width, |
293 | drawable->height, | 312 | drawable->height, |
294 | (format != 0)?format:drawable->depth, | 313 | (format != 0)?format:drawable->depth, |
295 | flags); | 314 | flags); |
315 | } | ||
296 | } | 316 | } |
297 | 317 | ||
298 | if (attachment == DRI2BufferDepth) { | 318 | if (attachment == DRI2BufferDepth) { |
@@ -423,7 +443,9 @@ radeon_dri2_copy_region(DrawablePtr drawable, | |||
423 | } | 443 | } |
424 | 444 | ||
425 | vsync = info->accel_state->vsync; | 445 | vsync = info->accel_state->vsync; |
426 | info->accel_state->vsync = TRUE; | 446 | |
447 | /* Driver option "SwapbuffersWait" defines if we vsync DRI2 copy-swaps. */ | ||
448 | info->accel_state->vsync = info->swapBuffersWait; | ||
427 | 449 | ||
428 | (*gc->ops->CopyArea)(src_drawable, dst_drawable, gc, | 450 | (*gc->ops->CopyArea)(src_drawable, dst_drawable, gc, |
429 | 0, 0, drawable->width, drawable->height, 0, 0); | 451 | 0, 0, drawable->width, drawable->height, 0, 0); |
@@ -549,12 +571,124 @@ radeon_dri2_unref_buffer(BufferPtr buffer) | |||
549 | } | 571 | } |
550 | } | 572 | } |
551 | 573 | ||
574 | static int radeon_dri2_drawable_crtc(DrawablePtr pDraw) | ||
575 | { | ||
576 | ScreenPtr pScreen = pDraw->pScreen; | ||
577 | ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; | ||
578 | xf86CrtcPtr crtc; | ||
579 | int crtc_id = -1; | ||
580 | |||
581 | crtc = radeon_pick_best_crtc(pScrn, | ||
582 | pDraw->x, | ||
583 | pDraw->x + pDraw->width, | ||
584 | pDraw->y, | ||
585 | pDraw->y + pDraw->height); | ||
586 | |||
587 | /* Make sure the CRTC is valid and this is the real front buffer */ | ||
588 | if (crtc != NULL && !crtc->rotatedData) { | ||
589 | crtc_id = drmmode_get_crtc_id(crtc); | ||
590 | } | ||
591 | return crtc_id; | ||
592 | } | ||
593 | |||
594 | static Bool | ||
595 | radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client, | ||
596 | DrawablePtr draw, DRI2BufferPtr front, | ||
597 | DRI2BufferPtr back, DRI2SwapEventPtr func, | ||
598 | void *data, unsigned int target_msc) | ||
599 | { | ||
600 | struct dri2_buffer_priv *back_priv; | ||
601 | struct radeon_exa_pixmap_priv *exa_priv; | ||
602 | DRI2FrameEventPtr flip_info; | ||
603 | |||
604 | /* Main crtc for this drawable shall finally deliver pageflip event. */ | ||
605 | int ref_crtc_hw_id = radeon_dri2_drawable_crtc(draw); | ||
606 | |||
607 | flip_info = calloc(1, sizeof(DRI2FrameEventRec)); | ||
608 | if (!flip_info) | ||
609 | return FALSE; | ||
610 | |||
611 | flip_info->drawable_id = draw->id; | ||
612 | flip_info->client = client; | ||
613 | flip_info->type = DRI2_SWAP; | ||
614 | flip_info->event_complete = func; | ||
615 | flip_info->event_data = data; | ||
616 | flip_info->frame = target_msc; | ||
617 | |||
618 | xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, | ||
619 | "%s:%d fevent[%p]\n", __func__, __LINE__, flip_info); | ||
620 | |||
621 | /* Page flip the full screen buffer */ | ||
622 | back_priv = back->driverPrivate; | ||
623 | exa_priv = exaGetPixmapDriverPrivate(back_priv->pixmap); | ||
624 | |||
625 | return radeon_do_pageflip(scrn, exa_priv->bo, flip_info, ref_crtc_hw_id); | ||
626 | } | ||
627 | |||
628 | static Bool | ||
629 | can_exchange(DRI2BufferPtr front, DRI2BufferPtr back) | ||
630 | { | ||
631 | struct dri2_buffer_priv *front_priv = front->driverPrivate; | ||
632 | struct dri2_buffer_priv *back_priv = back->driverPrivate; | ||
633 | PixmapPtr front_pixmap = front_priv->pixmap; | ||
634 | PixmapPtr back_pixmap = back_priv->pixmap; | ||
635 | |||
636 | if (front_pixmap->drawable.width != back_pixmap->drawable.width) | ||
637 | return FALSE; | ||
638 | |||
639 | if (front_pixmap->drawable.height != back_pixmap->drawable.height) | ||
640 | return FALSE; | ||
641 | |||
642 | if (front_pixmap->drawable.bitsPerPixel != back_pixmap->drawable.bitsPerPixel) | ||
643 | return FALSE; | ||
644 | |||
645 | if (front_pixmap->devKind != back_pixmap->devKind) | ||
646 | return FALSE; | ||
647 | |||
648 | return TRUE; | ||
649 | } | ||
650 | |||
651 | static void | ||
652 | radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back) | ||
653 | { | ||
654 | struct dri2_buffer_priv *front_priv = front->driverPrivate; | ||
655 | struct dri2_buffer_priv *back_priv = back->driverPrivate; | ||
656 | struct radeon_exa_pixmap_priv *front_radeon, *back_radeon; | ||
657 | ScreenPtr screen; | ||
658 | RADEONInfoPtr info; | ||
659 | struct radeon_bo *bo; | ||
660 | int tmp; | ||
661 | |||
662 | /* Swap BO names so DRI works */ | ||
663 | tmp = front->name; | ||
664 | front->name = back->name; | ||
665 | back->name = tmp; | ||
666 | |||
667 | /* Swap pixmap bos */ | ||
668 | front_radeon = exaGetPixmapDriverPrivate(front_priv->pixmap); | ||
669 | back_radeon = exaGetPixmapDriverPrivate(back_priv->pixmap); | ||
670 | bo = back_radeon->bo; | ||
671 | back_radeon->bo = front_radeon->bo; | ||
672 | front_radeon->bo = bo; | ||
673 | |||
674 | /* Do we need to update the Screen? */ | ||
675 | screen = draw->pScreen; | ||
676 | info = RADEONPTR(xf86Screens[screen->myNum]); | ||
677 | if (front_radeon->bo == info->front_bo) { | ||
678 | radeon_bo_unref(info->front_bo); | ||
679 | info->front_bo = back_radeon->bo; | ||
680 | radeon_bo_ref(info->front_bo); | ||
681 | front_radeon = exaGetPixmapDriverPrivate(screen->GetScreenPixmap(screen)); | ||
682 | front_radeon->bo = bo; | ||
683 | } | ||
684 | } | ||
685 | |||
552 | void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, | 686 | void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, |
553 | unsigned int tv_usec, void *event_data) | 687 | unsigned int tv_usec, void *event_data) |
554 | { | 688 | { |
555 | DRI2FrameEventPtr event = event_data; | 689 | DRI2FrameEventPtr event = event_data; |
690 | RADEONInfoPtr info; | ||
556 | DrawablePtr drawable; | 691 | DrawablePtr drawable; |
557 | ClientPtr client; | ||
558 | ScreenPtr screen; | 692 | ScreenPtr screen; |
559 | ScrnInfoPtr scrn; | 693 | ScrnInfoPtr scrn; |
560 | int status; | 694 | int status; |
@@ -563,7 +697,7 @@ void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, | |||
563 | RegionRec region; | 697 | RegionRec region; |
564 | 698 | ||
565 | if (!event->valid) | 699 | if (!event->valid) |
566 | goto cleanup; | 700 | goto cleanup; |
567 | 701 | ||
568 | status = dixLookupDrawable(&drawable, event->drawable_id, serverClient, | 702 | status = dixLookupDrawable(&drawable, event->drawable_id, serverClient, |
569 | M_ANY, DixWriteAccess); | 703 | M_ANY, DixWriteAccess); |
@@ -572,25 +706,46 @@ void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, | |||
572 | 706 | ||
573 | screen = drawable->pScreen; | 707 | screen = drawable->pScreen; |
574 | scrn = xf86Screens[screen->myNum]; | 708 | scrn = xf86Screens[screen->myNum]; |
575 | client = event->client; | 709 | info = RADEONPTR(scrn); |
576 | 710 | ||
577 | switch (event->type) { | 711 | switch (event->type) { |
578 | case DRI2_FLIP: | 712 | case DRI2_FLIP: |
713 | if (info->allowPageFlip && | ||
714 | DRI2CanFlip(drawable) && | ||
715 | can_exchange(event->front, event->back) && | ||
716 | radeon_dri2_schedule_flip(scrn, | ||
717 | event->client, | ||
718 | drawable, | ||
719 | event->front, | ||
720 | event->back, | ||
721 | event->event_complete, | ||
722 | event->event_data, | ||
723 | event->frame)) { | ||
724 | radeon_dri2_exchange_buffers(drawable, event->front, event->back); | ||
725 | break; | ||
726 | } | ||
727 | /* else fall through to exchange/blit */ | ||
579 | case DRI2_SWAP: | 728 | case DRI2_SWAP: |
580 | box.x1 = 0; | 729 | if (DRI2CanExchange(drawable) && |
581 | box.y1 = 0; | 730 | can_exchange(event->front, event->back)) { |
582 | box.x2 = drawable->width; | 731 | radeon_dri2_exchange_buffers(drawable, event->front, event->back); |
583 | box.y2 = drawable->height; | 732 | swap_type = DRI2_EXCHANGE_COMPLETE; |
584 | REGION_INIT(pScreen, ®ion, &box, 0); | 733 | } else { |
585 | radeon_dri2_copy_region(drawable, ®ion, event->front, event->back); | 734 | box.x1 = 0; |
586 | swap_type = DRI2_BLIT_COMPLETE; | 735 | box.y1 = 0; |
587 | 736 | box.x2 = drawable->width; | |
588 | DRI2SwapComplete(client, drawable, frame, tv_sec, tv_usec, | 737 | box.y2 = drawable->height; |
738 | REGION_INIT(pScreen, ®ion, &box, 0); | ||
739 | radeon_dri2_copy_region(drawable, ®ion, event->front, event->back); | ||
740 | swap_type = DRI2_BLIT_COMPLETE; | ||
741 | } | ||
742 | |||
743 | DRI2SwapComplete(event->client, drawable, frame, tv_sec, tv_usec, | ||
589 | swap_type, event->event_complete, event->event_data); | 744 | swap_type, event->event_complete, event->event_data); |
590 | 745 | ||
591 | break; | 746 | break; |
592 | case DRI2_WAITMSC: | 747 | case DRI2_WAITMSC: |
593 | DRI2WaitMSCComplete(client, drawable, frame, tv_sec, tv_usec); | 748 | DRI2WaitMSCComplete(event->client, drawable, frame, tv_sec, tv_usec); |
594 | break; | 749 | break; |
595 | default: | 750 | default: |
596 | /* Unknown type */ | 751 | /* Unknown type */ |
@@ -607,26 +762,6 @@ cleanup: | |||
607 | free(event); | 762 | free(event); |
608 | } | 763 | } |
609 | 764 | ||
610 | static int radeon_dri2_drawable_crtc(DrawablePtr pDraw) | ||
611 | { | ||
612 | ScreenPtr pScreen = pDraw->pScreen; | ||
613 | ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; | ||
614 | xf86CrtcPtr crtc; | ||
615 | int crtc_id = -1; | ||
616 | |||
617 | crtc = radeon_pick_best_crtc(pScrn, | ||
618 | pDraw->x, | ||
619 | pDraw->x + pDraw->width, | ||
620 | pDraw->y, | ||
621 | pDraw->y + pDraw->height); | ||
622 | |||
623 | /* Make sure the CRTC is valid and this is the real front buffer */ | ||
624 | if (crtc != NULL && !crtc->rotatedData) { | ||
625 | crtc_id = drmmode_get_crtc_id(crtc); | ||
626 | } | ||
627 | return crtc_id; | ||
628 | } | ||
629 | |||
630 | /* | 765 | /* |
631 | * Get current frame count and frame count timestamp, based on drawable's | 766 | * Get current frame count and frame count timestamp, based on drawable's |
632 | * crtc. | 767 | * crtc. |
@@ -638,7 +773,7 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) | |||
638 | RADEONInfoPtr info = RADEONPTR(scrn); | 773 | RADEONInfoPtr info = RADEONPTR(scrn); |
639 | drmVBlank vbl; | 774 | drmVBlank vbl; |
640 | int ret; | 775 | int ret; |
641 | int crtc= radeon_dri2_drawable_crtc(draw); | 776 | int crtc = radeon_dri2_drawable_crtc(draw); |
642 | 777 | ||
643 | /* Drawable not displayed, make up a value */ | 778 | /* Drawable not displayed, make up a value */ |
644 | if (crtc == -1) { | 779 | if (crtc == -1) { |
@@ -796,6 +931,59 @@ out_complete: | |||
796 | return TRUE; | 931 | return TRUE; |
797 | } | 932 | } |
798 | 933 | ||
934 | void radeon_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec, | ||
935 | unsigned int tv_usec, void *event_data) | ||
936 | { | ||
937 | DRI2FrameEventPtr flip = event_data; | ||
938 | DrawablePtr drawable; | ||
939 | ScreenPtr screen; | ||
940 | ScrnInfoPtr scrn; | ||
941 | int status; | ||
942 | PixmapPtr pixmap; | ||
943 | |||
944 | status = dixLookupDrawable(&drawable, flip->drawable_id, serverClient, | ||
945 | M_ANY, DixWriteAccess); | ||
946 | if (status != Success) { | ||
947 | free(flip); | ||
948 | return; | ||
949 | } | ||
950 | |||
951 | screen = drawable->pScreen; | ||
952 | scrn = xf86Screens[screen->myNum]; | ||
953 | |||
954 | pixmap = screen->GetScreenPixmap(screen); | ||
955 | xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, | ||
956 | "%s:%d fevent[%p] width %d pitch %d (/4 %d)\n", | ||
957 | __func__, __LINE__, flip, pixmap->drawable.width, pixmap->devKind, pixmap->devKind/4); | ||
958 | |||
959 | /* We assume our flips arrive in order, so we don't check the frame */ | ||
960 | switch (flip->type) { | ||
961 | case DRI2_SWAP: | ||
962 | /* Check for too small vblank count of pageflip completion, taking wraparound | ||
963 | * into account. This usually means some defective kms pageflip completion, | ||
964 | * causing wrong (msc, ust) return values and possible visual corruption. | ||
965 | */ | ||
966 | if ((frame < flip->frame) && (flip->frame - frame < 5)) { | ||
967 | xf86DrvMsg(scrn->scrnIndex, X_WARNING, | ||
968 | "%s: Pageflip completion event has impossible msc %d < target_msc %d\n", | ||
969 | __func__, frame, flip->frame); | ||
970 | /* All-Zero values signal failure of (msc, ust) timestamping to client. */ | ||
971 | frame = tv_sec = tv_usec = 0; | ||
972 | } | ||
973 | |||
974 | DRI2SwapComplete(flip->client, drawable, frame, tv_sec, tv_usec, | ||
975 | DRI2_FLIP_COMPLETE, flip->event_complete, | ||
976 | flip->event_data); | ||
977 | break; | ||
978 | default: | ||
979 | xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: unknown vblank event received\n", __func__); | ||
980 | /* Unknown type */ | ||
981 | break; | ||
982 | } | ||
983 | |||
984 | free(flip); | ||
985 | } | ||
986 | |||
799 | /* | 987 | /* |
800 | * ScheduleSwap is responsible for requesting a DRM vblank event for the | 988 | * ScheduleSwap is responsible for requesting a DRM vblank event for the |
801 | * appropriate frame. | 989 | * appropriate frame. |
@@ -883,6 +1071,15 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, | |||
883 | } | 1071 | } |
884 | 1072 | ||
885 | current_msc = vbl.reply.sequence; | 1073 | current_msc = vbl.reply.sequence; |
1074 | |||
1075 | /* Flips need to be submitted one frame before */ | ||
1076 | if (info->allowPageFlip && | ||
1077 | DRI2CanFlip(draw) && | ||
1078 | can_exchange(front, back)) { | ||
1079 | swap_type = DRI2_FLIP; | ||
1080 | flip = 1; | ||
1081 | } | ||
1082 | |||
886 | swap_info->type = swap_type; | 1083 | swap_info->type = swap_type; |
887 | 1084 | ||
888 | /* Correct target_msc by 'flip' if swap_type == DRI2_FLIP. | 1085 | /* Correct target_msc by 'flip' if swap_type == DRI2_FLIP. |
@@ -899,9 +1096,6 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, | |||
899 | */ | 1096 | */ |
900 | if (divisor == 0 || current_msc < *target_msc) { | 1097 | if (divisor == 0 || current_msc < *target_msc) { |
901 | vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; | 1098 | vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; |
902 | if (crtc > 0) | ||
903 | vbl.request.type |= DRM_VBLANK_SECONDARY; | ||
904 | |||
905 | /* If non-pageflipping, but blitting/exchanging, we need to use | 1099 | /* If non-pageflipping, but blitting/exchanging, we need to use |
906 | * DRM_VBLANK_NEXTONMISS to avoid unreliable timestamping later | 1100 | * DRM_VBLANK_NEXTONMISS to avoid unreliable timestamping later |
907 | * on. | 1101 | * on. |
diff --git a/src/radeon_dri2.h b/src/radeon_dri2.h index 688530f2..79952862 100644 --- a/src/radeon_dri2.h +++ b/src/radeon_dri2.h | |||
@@ -44,5 +44,7 @@ xf86CrtcPtr radeon_covering_crtc(ScrnInfoPtr pScrn, BoxPtr box, | |||
44 | xf86CrtcPtr desired, BoxPtr crtc_box_ret); | 44 | xf86CrtcPtr desired, BoxPtr crtc_box_ret); |
45 | void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, | 45 | void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, |
46 | unsigned int tv_usec, void *event_data); | 46 | unsigned int tv_usec, void *event_data); |
47 | void radeon_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec, | ||
48 | unsigned int tv_usec, void *event_data); | ||
47 | 49 | ||
48 | #endif | 50 | #endif |
diff --git a/src/radeon_exa.c b/src/radeon_exa.c index 9c40da79..9df7251e 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c | |||
@@ -318,6 +318,17 @@ Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index) | |||
318 | if (!driver_priv) | 318 | if (!driver_priv) |
319 | return FALSE; | 319 | return FALSE; |
320 | 320 | ||
321 | if (info->ChipFamily >= CHIP_FAMILY_R600) { | ||
322 | uint32_t tiling_flags = 0, pitch = 0; | ||
323 | |||
324 | ret = radeon_bo_get_tiling(driver_priv->bo, &tiling_flags, &pitch); | ||
325 | if (ret) | ||
326 | return FALSE; | ||
327 | /* untile in DFS/UTS */ | ||
328 | if (tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO)) | ||
329 | return FALSE; | ||
330 | } | ||
331 | |||
321 | /* if we have more refs than just the BO then flush */ | 332 | /* if we have more refs than just the BO then flush */ |
322 | if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { | 333 | if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { |
323 | flush = TRUE; | 334 | flush = TRUE; |
diff --git a/src/radeon_kms.c b/src/radeon_kms.c index f4c54b30..59f82818 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c | |||
@@ -70,6 +70,8 @@ const OptionInfoRec RADEONOptions_KMS[] = { | |||
70 | { OPTION_EXA_VSYNC, "EXAVSync", OPTV_BOOLEAN, {0}, FALSE }, | 70 | { OPTION_EXA_VSYNC, "EXAVSync", OPTV_BOOLEAN, {0}, FALSE }, |
71 | { OPTION_EXA_PIXMAPS, "EXAPixmaps", OPTV_BOOLEAN, {0}, FALSE }, | 71 | { OPTION_EXA_PIXMAPS, "EXAPixmaps", OPTV_BOOLEAN, {0}, FALSE }, |
72 | { OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE }, | 72 | { OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE }, |
73 | { OPTION_PAGE_FLIP, "EnablePageFlip", OPTV_BOOLEAN, {0}, FALSE }, | ||
74 | { OPTION_SWAPBUFFERS_WAIT,"SwapbuffersWait", OPTV_BOOLEAN, {0}, FALSE }, | ||
73 | { -1, NULL, OPTV_NONE, {0}, FALSE } | 75 | { -1, NULL, OPTV_NONE, {0}, FALSE } |
74 | }; | 76 | }; |
75 | 77 | ||
@@ -620,6 +622,18 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) | |||
620 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, | 622 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, |
621 | "KMS Color Tiling: %sabled\n", info->allowColorTiling ? "en" : "dis"); | 623 | "KMS Color Tiling: %sabled\n", info->allowColorTiling ? "en" : "dis"); |
622 | 624 | ||
625 | if (info->dri->pKernelDRMVersion->version_minor >= 8) { | ||
626 | info->allowPageFlip = xf86ReturnOptValBool(info->Options, | ||
627 | OPTION_PAGE_FLIP, TRUE); | ||
628 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, | ||
629 | "KMS Pageflipping: %sabled\n", info->allowPageFlip ? "en" : "dis"); | ||
630 | } | ||
631 | |||
632 | info->swapBuffersWait = xf86ReturnOptValBool(info->Options, | ||
633 | OPTION_SWAPBUFFERS_WAIT, TRUE); | ||
634 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, | ||
635 | "SwapBuffers wait for vsync: %sabled\n", info->swapBuffersWait ? "en" : "dis"); | ||
636 | |||
623 | if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) { | 637 | if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) { |
624 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n"); | 638 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n"); |
625 | goto fail; | 639 | goto fail; |
@@ -678,7 +692,9 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) | |||
678 | 692 | ||
679 | /* no tiled scanout on r6xx+ yet */ | 693 | /* no tiled scanout on r6xx+ yet */ |
680 | if (info->allowColorTiling) { | 694 | if (info->allowColorTiling) { |
681 | if (info->ChipFamily < CHIP_FAMILY_R600) | 695 | if (info->ChipFamily >= CHIP_FAMILY_R600) |
696 | tiling |= RADEON_TILING_MICRO; | ||
697 | else | ||
682 | tiling |= RADEON_TILING_MACRO; | 698 | tiling |= RADEON_TILING_MACRO; |
683 | } | 699 | } |
684 | cpp = pScrn->bitsPerPixel / 8; | 700 | cpp = pScrn->bitsPerPixel / 8; |
@@ -1115,9 +1131,10 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) | |||
1115 | return FALSE; | 1131 | return FALSE; |
1116 | } | 1132 | } |
1117 | 1133 | ||
1118 | /* no tiled scanout on r6xx+ yet */ | ||
1119 | if (info->allowColorTiling) { | 1134 | if (info->allowColorTiling) { |
1120 | if (info->ChipFamily < CHIP_FAMILY_R600) | 1135 | if (info->ChipFamily >= CHIP_FAMILY_R600) |
1136 | tiling_flags |= RADEON_TILING_MICRO; | ||
1137 | else | ||
1121 | tiling_flags |= RADEON_TILING_MACRO; | 1138 | tiling_flags |= RADEON_TILING_MACRO; |
1122 | } | 1139 | } |
1123 | pitch = RADEON_ALIGN(pScrn->displayWidth, drmmode_get_pitch_align(pScrn, cpp, tiling_flags)) * cpp; | 1140 | pitch = RADEON_ALIGN(pScrn->displayWidth, drmmode_get_pitch_align(pScrn, cpp, tiling_flags)) * cpp; |